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

esp*_*eed 2 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
Run Code Online (Sandbox Code Playgroud)

这适用于未定义为属性的普通属性,因为Super调用object的setattr来阻止递归循环.

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

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

@some_prop.setter
def some_prop(self, value):
    super(TypeSystem, self).__setattr__("some_prop", value)
Run Code Online (Sandbox Code Playgroud)

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

agf*_*agf 10

这与__setattr__你的无关TypeSystem.你的问题是

@some_prop.setter
def some_prop(self,value):
    self.some_prop = value
Run Code Online (Sandbox Code Playgroud)

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

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

some_prop = self.some_prop
Run Code Online (Sandbox Code Playgroud)

也将导致无限循环 - 你试图获得属性的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
Run Code Online (Sandbox Code Playgroud)