如何避免使用__setattr__和属性设置器的递归循环?
当调用 setattr 函数时,如果试图为 some_prop 这个属性设置值,就会导致无限递归循环,因为 some_prop 是一个有设置器的属性。
class TypeSystem(object):
def __setattr__(self, key, value):
if the_special_case is True:
# do something
else:
super(TypeSystem,self).__setattr__(key,value)
class Entity(TypeSystem):
@property
def some_prop(self):
some_prop = self.data.get('some_prop')
if some_prop is None and hasattr(self,"some_prop"):
some_prop = self.some_prop
return some_prop
@some_prop.setter
def some_prop(self,value):
self.some_prop = value
>>> entity = Entity()
>>> entity.some_prop = 3
对于那些没有定义为属性的普通属性,这种情况不会出现问题,因为 Super 会调用对象的 setattr 来防止递归循环。
但是,由于 some_prop 不是预先定义的,所以看起来是调用了 setattr,而不是 some_prop 的设置器,这就导致了循环。
我也尝试过这个……
@some_prop.setter
def some_prop(self, value):
super(TypeSystem, self).__setattr__("some_prop", value)
但它仍然进入了递归循环。我不知道该怎么避免这个问题。
1 个回答
10
这和 __setattr__
或你的 TypeSystem
没什么关系。你遇到的问题是
@some_prop.setter
def some_prop(self,value):
self.some_prop = value
这明显是一个无限循环——你在属性的设置方法里又试图设置这个属性。
在获取方法里你也有同样的问题:
some_prop = self.some_prop
这也会导致无限循环——你在属性的获取方法里又试图获取这个属性。
你需要用另一个变量来保存实际的数据:
class Entity(TypeSystem):
@property
def some_prop(self):
some_prop = self.data.get('some_prop')
if some_prop is None and hasattr(self,"_some_prop"):
some_prop = self._some_prop
return some_prop
@some_prop.setter
def some_prop(self,value):
self._some_prop = value