[英]Python's property decorator does not work as expected
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
But it does not print "You are getting silly", "You are making silly funny",... as expected. 但它没有打印出“你变得愚蠢”,“你正在制造愚蠢的搞笑”,......正如预期的那样。 Don't know why.
不知道为什么。 Can you have me figure out, folks?
亲爱的,你能让我弄清楚吗?
Thanks in advance! 提前致谢!
The property
decorator only works with new-style classes ( see also ). property
装饰器仅适用于新式类 ( 另请参见 )。 Make Silly
extend from object
explicitly to make it a new-style class. Make
Silly
明确地从object
扩展,使其成为一个新式的类。 (In Python 3, all classes are new-style classes) (在Python 3中,所有类都是新式类)
class Silly(object):
@property
def silly(self):
# ...
# ...
As you most likely are aware of the correct method to add properties would be to use: 您很可能知道添加属性的正确方法是使用:
@property
def silly(self):
return self._silly
@silly.setter:
def silly(self, value):
self._silly = value
But this requires new style classes, that is that somewhere in the chain there is supposed to be a class ParentClass(object):
. 但是这需要新的样式类,即链中的某个地方应该是一个
class ParentClass(object):
The similar option of using silly = property(get_silly, set_silly)
has the same requirement. 使用
silly = property(get_silly, set_silly)
的类似选项具有相同的要求。
However, there is another option, and that is to use a corresponding private variable, like self._silly
, and override the __getattr__
and __setattr__
methods: 但是,还有另一种选择,即使用相应的私有变量,如
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
Notice how __getattr__
will be called after checking for other attributes, but that __setattr__
is called before checking for other attributes. 注意在检查其他属性后如何调用
__getattr__
,但在检查其他属性之前调用__setattr__
。 Therefore the former can and should raise an error if not an accepted attribute, and the latter should set the attribute. 因此,如果不是可接受的属性,前者可以而且应该引发错误,后者应该设置属性。 Do not use
self._silly = value
within __setattr__
as that would cause infinite recursion. 不要使用
self._silly = value
内__setattr__
因为这将导致无限递归。
Also note that since we're dealing with old style classes here, you should actually use the dict method, and not the newer baseclass.__setattr__(self, attr, value)
, see docs . 另请注意,由于我们在这里处理旧样式类,您实际上应该使用dict方法,而不是更新的
baseclass.__setattr__(self, attr, value)
,请参阅docs 。 A similar __delattr__()
does also exist, if you want it. 如果你需要,也会存在类似的
__delattr__()
。
Using this code, you can now do stuff like: 使用此代码,您现在可以执行以下操作:
i_am = Silly()
i_am.silly = 'No, I'm clever'
print i_am.silly
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.