Python类Property Setter失效问题:基于外部类扩展时属性设置异常
问题根源:重写
__setattr__绕过了Property的Setter 你的问题出在重写的__setattr__方法拦截了所有属性赋值操作,导致index的setter完全没被触发。
让我们拆解一下执行流程:
- 当你执行
super_object.index = 3时,Python会优先调用SuperClass的__setattr__方法,传入attr='index'和val=3 - 你的
__setattr__逻辑里,只有当属性是_SuperClass__main时才会直接设置自己的属性,其他所有情况都把赋值转发给self.__main(也就是main_object) - 但
main_object是MainClass的实例,根本没有index属性,这一步其实是给main_object新增了一个无关的index属性,而SuperClass自己的_index变量完全没被修改,所以后续indexgetter返回的还是初始值0
解决方案:区分自己的属性和转发的属性
我们需要修改__setattr__,让它先判断当前属性是否是SuperClass自己应该处理的(比如类定义的property、自己的实例变量),如果是就直接设置自身属性,否则再转发给self.__main。
修改后的代码如下:
class MainClass(object): def __init__(self): self.name = 'abc' class SuperClass(object): def __init__(self, main, *args, **kwargs): super(SuperClass, self).__init__(*args, **kwargs) self.__main = main self._index = 0 def __getattr__(self, attr): return getattr(self.__main, attr) def __setattr__(self, attr, val): # 优先处理自己的属性:私有__main变量、类定义的属性(包括property)、保护变量_index if attr == '_SuperClass__main' or hasattr(type(self), attr) or attr == '_index': object.__setattr__(self, attr, val) return # 其他属性转发给__main实例 setattr(self.__main, attr, val) @property def index(self): return self._index @index.setter def index(self, value): self._index = value main_object = MainClass() super_object = SuperClass(main_object) print('x', super_object.index, super_object.name) super_object.index = 3 print('y', super_object.index) super_object.index += 2 print('z', super_object.index)
执行结果说明
修改后运行代码会输出:
x 0 abc y 3 z 5
这里的关键改进是:
- 用
hasattr(type(self), attr)判断属性是否是SuperClass类定义的(比如index这个property),是的话就直接调用object.__setattr__处理,这样就能触发property的setter - 同时显式包含
_index,确保保护变量的赋值也能直接作用于自身实例
另外补充一点:__getattr__是只有当实例本身没有该属性时才会被调用,所以index作为类级别的property,不会触发__getattr__,这部分逻辑是没问题的。
内容的提问来源于stack exchange,提问作者Psionman
相关产品推荐
相关产品推荐

