Python的属性装饰器未按预期工作

4
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

但是它并没有像预期的那样打印出 "You are getting silly","You are making silly funny" 等内容。不知道为什么。你能帮我找出原因吗?谢谢!
2个回答

17

property装饰器仅适用于新式类参见)。请显式让Silly继承自以使其成为新式类。(在Python 3中,所有的类都是新式类)

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


类Silly --> 类Silly(对象),它起作用了。我错过了。谢谢! - Locke

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

请注意,__getattr__ 在检查其他属性之后才会被调用,而 __setattr__ 在检查其他属性之前就被调用了。因此,前者可以并且应该在不接受属性时引发错误,而后者应该设置属性。在 __setattr__ 中不要使用 self._silly = value,因为这会导致无限递归。
另外,请注意,由于我们在处理旧式类,你应该实际使用 dict 方法,而不是较新的 baseclass.__setattr__(self, attr, value),请参见 docs。如果需要,还存在类似的 __delattr__()
使用此代码,您现在可以执行以下操作:
i_am = Silly()
i_am.silly = 'No, I'm clever'
print i_am.silly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接