首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python的属性装饰器无法按预期工作

Python的属性装饰器无法按预期工作
EN

Stack Overflow用户
提问于 2012-04-01 13:04:06
回答 2查看 2.1K关注 0票数 4
代码语言:javascript
复制
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

但是它不会打印“你变傻了”,“你变得傻了”,……不出所料。不知道为什么。你们能让我搞清楚吗,伙计们?

提前感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-01 13:05:43

The property decorator仅适用于new-style classes (see also)。使Silly显式地从object扩展,使其成为一个新风格的类。(在Python 3中,所有类都是新风格的类)

代码语言:javascript
复制
class Silly(object):
    @property
    def silly(self):
        # ...
    # ...
票数 16
EN

Stack Overflow用户

发布于 2015-11-21 20:13:53

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

代码语言:javascript
复制
@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__方法:

代码语言:javascript
复制
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__()也确实存在。

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

代码语言:javascript
复制
i_am = Silly()
i_am.silly = 'No, I'm clever'
print i_am.silly
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9962037

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档