如何避免使用__setattr__和属性设置器的递归循环?

时间:2011-09-17 04:14:57

标签: python

当调用setattr时,当尝试设置some_prop的值时,这会导致无限递归循环,some_prop是具有setter的属性:

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调用object的setattr来阻止递归循环。

但是因为some_prop没有预先定义,所以看起来调用setattr而不是some_prop的setter,所以它被拉入循环。

我也试过这个......

@some_prop.setter
def some_prop(self, value):
    super(TypeSystem, self).__setattr__("some_prop", value)

但它仍然进入递归循环。我没有看到如何避免它。

1 个答案:

答案 0 :(得分:10)

这与__setattr__或您的TypeSystem无关。你的问题是

@some_prop.setter
def some_prop(self,value):
    self.some_prop = value

这显然是一个无限循环 - 你试图在属性的setter中设置属性。

你在getter中遇到同样的问题:

some_prop = self.some_prop

也会导致无限循环 - 你试图在属性的getter中获取属性。

您需要使用另一个变量来保存实际数据:

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