Python'Property'表现得很奇怪

时间:2018-02-06 11:41:52

标签: python properties

请看下面的代码。

class CCC:
    @property
    def n(self):
        print('getter called')
        return self.__dict__['n']

    @n.setter
    def n(self, value):
        print('setter called')
        self.__dict__['n'] = value


c = CCC()
c.n = 5
print(CCC.__dict__)
print(c.__dict__)
print(c.n)

这是执行的结果

setter called
{'__module__': '__main__', 'n': <property object at 0x000000000289CC28>, '__dict__': <attribute '__dict__' of 'CCC' objects>, '__weakref__': <attribute '__weakref__' of 'CCC' objects>, '__doc__': None}
{'n': 5}
getter called # I do not understand why this sentence is printed. 
5

我不明白为什么打印'getter'。 CCC有一个n属性对象。 c的整数为n。当我打印c.n时,必须只打印c.\__dict__['n']。相反,打印了'getter called'。我有什么误会?

1 个答案:

答案 0 :(得分:2)

首先,除非你真的知道你正在做什么并且确实需要它,否则你不应该弄乱__dict__(或任何被__包围的东西)。

也就是说,使用getter(隐式)和setter(显式)创建属性。当setter在那里分配值时,getter返回值self.__dict__['n']

稍后,您创建CCC的实例并使用c.n = 5中的setter。然后,您打印__dict__类的CCC,告诉您有一个名为n的属性。之后,您会看到实例__dict__的{​​{1}}因设置而保留值c

因此,您在执行5时访问n属性。当您执行c.n时,您还会获得存储在那里的值,您通过设置器将其定义为self.__dict__['n']

既然你在getter中写了一个5函数,那就是你打印的内容。

也许通过调用setter / getter中print中的键来帮助你整理你的想法

__dict__

现在,我们不会在属性class CCC: @property def n(self): print('getter called') return self.__dict__['nval'] @n.setter def n(self, value): print('setter called') self.__dict__['nval'] = value c = CCC() c.n = 5 print(CCC.__dict__) print(c.__dict__) print(c.n) n中的密钥之间发生心理名称冲突。