Python属性装饰器不能按预期工作

时间:2012-04-01 05:04:06

标签: python class properties decorator new-style-class

class Silly:
    @property
    def silly(self):
        "This is a silly property"
        print("You are getting silly")
        return self._silly

    @silly.setter
    def silly(self, value):
        print("You are making silly {}".format(value))
        self._silly = value

    @silly.deleter
    def silly(self):
        print("Whoah, you killed silly!")
        del self._silly

s = Silly()
s.silly = "funny"
value = s.silly
del s.silly

但它没有打印出“你变得愚蠢”,“你正在制造愚蠢的搞笑”,......正如预期的那样。不知道为什么。伙计,你能让我弄清楚吗?

提前致谢!

2 个答案:

答案 0 :(得分:15)

The property decorator仅适用于new-style classessee also)。使Silly明确地从object延伸,使其成为新式的类。 (在Python 3中,所有类都是新式类)

class Silly(object):
    @property
    def silly(self):
        # ...
    # ...

答案 1 :(得分:0)

您很可能知道添加属性的正确方法是使用:

@property
def silly(self):
    return self._silly


@silly.setter:
def silly(self, value):
    self._silly = value

但是这需要新的样式类,即链中的某个地方应该是class ParentClass(object):。使用silly = property(get_silly, set_silly)的类似选项具有相同的要求。

但是,还有另一个选项,即使用相应的私有变量,例如self._silly,并覆盖__getattr____setattr__方法:

def __getattr__(self, name): 
    """Called _after_ looking in the normal places for name."""  

    if name == 'silly':
        self._silly
    else:
        raise AttributeError(name)


def __setattr__(self, name, value):
    """Called _before_ looking in the normal places for name."""
    if name == 'silly':
        self.__dict__['_silly'] = value
    else:
        self.__dict__[name] = value

注意在检查其他属性后如何调用{em> ,但在检查其他属性之前__getattr__被称为。因此,如果不是可接受的属性,前者可以而且应该引发错误,后者应该设置属性。 __setattr__中使用self._silly = value,因为这会导致无限递归。

另请注意,由于我们在此处理旧样式类,因此您应该使用dict方法,而不是较新的__setattr__,请参阅docs。如果您需要,也会存在类似的baseclass.__setattr__(self, attr, value)

使用此代码,您现在可以执行以下操作:

__delattr__()