Python类变量为何无法在对象间共享?如何实现静态共享变量?
问题原因分析
当你通过a.stream = 'ece'这种方式修改变量时,并没有改变类本身的stream变量,而是给实例a创建了一个同名的实例属性,把类变量给“遮蔽”了:
- Python查找属性时,会优先从实例自己的属性字典(
__dict__)里找,找不到才会去类的属性字典里找。 - 赋值
a.stream = 'ece'后,a的属性字典里多了stream键,之后访问a.stream只会读取这个实例属性,和类里的stream彻底无关。 - 此时
CSStudent.stream还是初始值'cse',其他没被赋值的实例(比如未执行b.stream = ...的b)访问b.stream时,因为自己没有这个实例属性,才会去类里读取类变量。
你代码里的注释有误:执行a.stream = 'ece'后,CSStudent.stream的输出应该是'cse',而不是'ece',只有通过类名修改才会改变类变量的值。
实现对象间共享类变量的正确方法
1. 通过类名直接修改类变量
要让所有实例共享修改,必须直接修改类本身的变量:
# Class for Computer Science Student class CSStudent: stream = 'cse' # Class Variable def __init__(self,name): self.name = name # Instance Variable a = CSStudent('Geek') b = CSStudent('Nerd') # 通过类名修改类变量 CSStudent.stream = 'ece' print(CSStudent.stream) # 输出 'ece' print(a.stream) # 输出 'ece'(a没有自己的stream实例属性,读取类变量) print(b.stream) # 输出 'ece'
2. 在实例方法中修改类变量
如果需要在实例方法里修改共享变量,要用self.__class__或者直接类名来引用类:
class CSStudent: stream = 'cse' def __init__(self, name): self.name = name def update_stream(self, new_stream): # 使用self.__class__获取实例所属的类,避免硬编码类名 self.__class__.stream = new_stream a = CSStudent('Geek') b = CSStudent('Nerd') a.update_stream('abc') print(a.stream) # 输出 'abc' print(b.stream) # 输出 'abc' print(CSStudent.stream) # 输出 'abc'
3. 恢复被遮蔽的类变量访问
如果不小心给实例赋值了同名变量,可通过del删除实例属性,恢复对类变量的访问:
a.stream = 'temp' # 给a添加实例属性,遮蔽类变量 del a.stream # 删除实例属性 print(a.stream) # 重新读取类变量的值
内容的提问来源于stack exchange,提问作者Vinay Vishwakarma
相关产品推荐
相关产品推荐

