Python继承中的类变量共享机制疑问及代码解析咨询
解析Python继承中类变量的共享问题
这是个非常经典的Python类变量坑!先来看你这段代码的实际运行结果,咱们对着结果一步步分析:
Initial Values 0 {} 0 {} Changing Values Print values after change 0 {'temp': 'something'} 1 {'temp': 'something'}
你肯定疑惑:为啥修改子类b的变量后,父类a的var1没变化,但var2却被悄悄改了?核心原因在于不可变类型和可变类型在类变量中的处理逻辑完全不一样。
1. 不可变类变量(比如var1 = 0)的行为
当你在b.modify_var()里执行cls.var1 = 1时:
cls在这里指代子类b,这个操作相当于给b类单独创建了一个属于自己的类变量var1,直接覆盖了从父类a继承来的那个var1。- 父类
a的var1根本没被碰过,所以o1.print_var()输出的还是最初的0,而o2用的是子类b自己的var1,自然输出1。
2. 可变类变量(比如var2 = {})的行为
而执行cls.var2['temp']="something"时,情况就完全不同了:
- 这里并没有给
b类新建一个var2,而是直接修改了var2这个字典对象本身的内容。 - 字典是可变类型,子类
b从父类a继承来的var2,和父类a自己的var2指向的是同一个内存地址里的字典对象。所以只要修改这个对象的内部元素,所有引用它的地方(父类的实例、子类的实例)都会同步看到变化。
直观验证:打印内存地址
你可以在代码里加两行打印内存地址的代码,一眼就能看明白:
print("var2地址:", id(a.var2), id(b.var2))
不管调用modify_var()前后,这两个地址都是完全相同的——说明它们是同一个字典;而a.var1和b.var1在调用modify_var()后,地址会变得不一样,因为b已经创建了自己的var1。
如何避免这种意外共享?
如果你想让子类拥有独立的可变类变量,只需要在子类里重新初始化它就行:
class b(a): var2 = {} # 重新初始化,给子类创建专属的字典 @classmethod def modify_var(cls): cls.var1 = 1 cls.var2['temp']="something"
这样修改子类的var2时,就完全不会影响父类的var2了。
内容的提问来源于stack exchange,提问作者Sourabh Jaiswal
相关产品推荐
相关产品推荐

