我观察到TensorFlow
方法,如assign_add
和assign_sub
,修改了对象和类的变量(如果存在的话)。下面是一个简单的代码来重现我的观察。有人能澄清一下这个行为吗(assign_sub
和assign_add
修改了类和示例属性)?
#a python class
class myc_base():
a=1.
def __init__(self, b=1.):
self.b=b
def add(self, to_add=1.):
self.a+=to_add
self.b+=to_add
def sub(self, to_sub=1.):
self.a-=to_sub
self.b-=to_sub
obj_base=myc_base()
print(f'Init. -- class.a: {myc_base.a} | obj.a: {obj_base.a}, obj.b: {obj_base.b}')
obj_base.add(5.)
print(f'after add -- class.a: {myc_base.a} | obj.a: {obj_base.a}, obj.b: {obj_base.b}')
obj_base.sub(2.)
print(f'after sub -- class.a: {myc_base.a} | obj.a: {obj_base.a}, obj.b: {obj_base.b}')
输出量:
Init. -- class.a: 1.0 | obj.a: 1.0, obj.b: 1.0
after add -- class.a: 1.0 | obj.a: 6.0, obj.b: 6.0
after sub -- class.a: 1.0 | obj.a: 4.0, obj.b: 4.0
使用TensorFlow:
import tensorflow as tf
#a class for tf operations
class myc_tf():
a=tf.Variable(1.)
def __init__(self, b=tf.Variable(1.)):
self.b=b
def add(self, to_add=1.):
self.a.assign_add(to_add)
self.b.assign_add(to_add)
def sub(self, to_sub=1.):
self.a.assign_sub(to_sub)
self.b.assign_sub(to_sub)
obj_tf=myc_tf()
print(f'Init. -- class.a: {myc_tf.a.numpy()} | obj.a: {obj_tf.a.numpy()}, obj.b: {obj_tf.b.numpy()}')
obj_tf.add(5.)
print(f'after add -- class.a: {myc_tf.a.numpy()} | obj.a: {obj_tf.a.numpy()}, obj.b: {obj_tf.b.numpy()}')
obj_tf.sub(2.)
print(f'after sub -- class.a: {myc_tf.a.numpy()} | obj.a: {obj_tf.a.numpy()}, obj.b: {obj_tf.b.numpy()}')
输出量:
Init. -- class.a: 1.0 | obj.a: 1.0, obj.b: 1.0
after add -- class.a: 6.0 | obj.a: 6.0, obj.b: 6.0
after sub -- class.a: 4.0 | obj.a: 4.0, obj.b: 4.0
2条答案
按热度按时间ymzxtsji1#
a
是类属性。b
是示例属性。然而,像这样的扩充作业
不会修改您认为通过示例访问的类属性。
因此第一次使用时,在RHS上访问class属性,但随后创建了一个新的示例属性,该示例属性在所有将来的调用中遮蔽class属性。
如果你想通过一个示例来修改一个类属性,你需要明确地修改它。一个可能的解决方案是:
您的TensorFlow代码不会进行任何赋值、增强或其他操作。它只是对
self.a
解析为的任何内容的方法调用,即类属性。不会创建新的示例属性。6jygbczu2#
当类使用你创建的变量和init()函数初始化时,你需要理解类和局部变量。assign_add()和assign_sub()被更新并等待值更新,但python类一旦释放或重新赋值就会被擦除。
示例:var1和var2都从10开始,var2以100作为局部变量,在类及其函数中使用。通过为var1分配更多的30作为局部变量。更新可以达到var1为40,var2为10,因为var2从不在函数之外,结果为100。
输出:本地var1、本地var2(无赋值函数)和数据(类更新的结果)