>>> class foo():
... @property
... def o(self):
... return 'o'
...
>>> f = foo()
>>> f.o
'o'
>>> f.__dict__['o'] = 'f'
>>> f.o
'f'
>>> class foo(object):
... @property
... def o(self):
... return 'o'
...
>>> f = foo()
>>> f.o
'o'
>>> f.__dict__['o'] = 'f'
>>> f.o
'o'
__dict__
集合没有出现。有什么想法吗?
我认为也许Python内部对待属性的方式有所不同,但我不确定,如果你自己编写一个属性类,那么该集合就会工作,否则就不行。
最佳答案
@property
def o(self):
return 'o'
这是一个非数据描述符,即没有定义 setter 的属性。因此实例属性可以覆盖此属性。
来自docs :
If an instance’s dictionary has an entry with the same name as a non-data descriptor, the dictionary entry takes precedence.
因此,要更新属性,还要定义其 setter 方法。
并且不要使用实例的 __dict__
来访问 setter 或 getter,内部 setter 的 f.o = 'f'
实际上会转换为:
type(f).__dict__['o'].__set__(f, 'f')
演示:
class Foo:
def __init__(self):
self._o = 'o'
@property
def o(self):
return self._o
@o.setter
def o(self, val):
self._o = val
>>> f = Foo()
>>> f.o
'o'
>>> type(f).__dict__['o'].__set__(f, 'f')
>>> f.o
'f'
>>> f.o = 'zzzz' #this is equivalent to the previous call.
>>> f.o
'zzzz'
>>> type(f).__dict__['o'].__set__(f, 'foo')
>>> f.o
'foo'
关于Python新样式类不能使用__dict__来更新property属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21850140/