请看下面的代码。
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'。我有什么误会?
答案 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
中的密钥之间发生心理名称冲突。