Python新样式类不能使用__dict__来更新属性属性

时间:2014-02-18 10:00:19

标签: python

>>> 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可能会对内部的属性有所不同,但我不确定,如果你自己编写一个属性类,该集合将起作用,否则不行。

1 个答案:

答案 0 :(得分:3)

@property
def o(self):
    return 'o'

这是一个非数据描述符,即没有定义setter的属性。因此,实例属性可以覆盖此属性。

来自docs

  

如果实例的字典有一个与a同名的条目   非数据描述符,字典条目优先。

因此,要更新属性,也要定义其setter方法。

并且不要使用实例的__dict__来访问setter或getter,内部f.o = 'f'实际上将setter转换为:

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'