You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TensorFlow的assign_add/assign_sub为何同时修改类与实例变量?

为什么TensorFlow的assign_add/assign_sub会同时修改类变量和实例变量?

这个现象的核心原因是Python中可变对象与不可变对象的行为差异,结合TensorFlow tf.Variable的特性导致的:

1. 普通Python类的行为解析

在普通Python类myc_base中:

  • 类变量a=1.是不可变类型(float)。不可变类型的特点是无法修改对象本身的内容,任何"修改"操作都会创建一个新的对象。
  • 当实例调用self.a += to_add时,实际执行逻辑是:
    1. 读取类变量a的初始值1.
    2. 计算1. + 5. = 6.,创建一个新的float对象6.
    3. 将这个新对象赋值给实例属性self.a
  • 此时实例的a已经脱离了对类变量的引用,拥有了独立的实例属性,所以后续修改只会影响实例自身,类变量保持不变。

你可以通过打印对象ID验证这一点:

print(f"Init: class.a id={id(myc_base.a)}, obj.a id={id(obj_base.a)}") # 初始时ID相同
obj_base.add(5.)
print(f"After add: class.a id={id(myc_base.a)}, obj.a id={id(obj_base.a)}") # ID不同,说明是两个独立对象

2. TensorFlow类的行为解析

在TensorFlow类myc_tf中:

  • 类变量a=tf.Variable(1.)是可变类型。tf.Variable是封装数值的可变容器,允许直接修改内部存储的数值,不需要创建新的Variable对象。
  • 当实例调用self.a.assign_add(to_add)时:
    1. 实例的self.a在未被重新赋值的情况下,始终指向类变量的那个tf.Variable实例(可以用id(myc_tf.a) == id(obj_tf.a)验证)
    2. assign_add方法直接修改了这个可变对象内部的数值,而非创建新的Variable
  • 因为类变量和实例变量指向的是同一个可变对象,修改对象内部值后,两者读取到的数值会同步变化。

而实例的b是在__init__中创建的独立tf.Variable,所以self.b.assign_add只会修改这个实例专属的Variable,不会影响其他实例或类属性。

总结

  • 不可变类型(如int、float、str):"修改"操作会创建新对象,实例属性会脱离类变量的引用
  • 可变类型(如tf.Variable、list、dict):修改操作直接改变对象内部内容,若实例属性未重新赋值,会始终指向类变量的同一个对象,导致类变量和实例变量同步变化

内容的提问来源于stack exchange,提问作者learner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:10:27