修改Python类属性未达预期,求分析认知误区
关于Python类属性与实例属性的认知误区
问题复现代码
class c_event(): cl_attr = None def __init__(self, mystring): print(self.cl_attr) if self.cl_attr is None: self.cl_attr = mystring print(self.cl_attr) var1 = c_event('123') var2 = c_event('456') print(var1.cl_attr) print(var2.cl_attr) print(c_event.cl_attr)
预期输出
None 123 123 123 123 123 123
实际输出
None 123 None 456 123 456 None
认知误区解析
你对类属性“共享可读写”的理解没错,但错在通过self赋值属性的逻辑:
- 读取
self.cl_attr时,会先找实例自身的属性,找不到才会读取类属性; - 但执行
self.cl_attr = mystring时,并不是修改类属性,而是给当前实例创建了一个同名的实例属性,这个实例属性会覆盖对类属性的读取。
具体到代码运行流程:
- 创建
var1时,第一次print(self.cl_attr)找不到实例属性,读取类属性None;随后self.cl_attr = '123'给var1新增了实例属性,此时var1的cl_attr和类属性无关。 - 创建
var2时,第一次print(self.cl_attr)同样读取类属性None;随后self.cl_attr = '456'给var2新增了自己的实例属性。 - 最后打印时,
var1.cl_attr和var2.cl_attr是各自的实例属性,而c_event.cl_attr始终是未被修改的类属性None。
修正后的代码
要真正修改类属性,需直接通过类名访问,这样所有实例才会共享类属性的修改:
class c_event(): cl_attr = None def __init__(self, mystring): print(c_event.cl_attr) if c_event.cl_attr is None: c_event.cl_attr = mystring print(c_event.cl_attr) var1 = c_event('123') var2 = c_event('456') print(var1.cl_attr) print(var2.cl_attr) print(c_event.cl_attr)
内容的提问来源于stack exchange,提问作者LudgerH
相关产品推荐
相关产品推荐

