使用python时遇到了一个奇怪的问题。考虑以下代码:
class Foo:
__bar=None
foo=Foo()
foo.bar=10
print(foo.bar)
我相信我应该在这里得到一个错误。但我得到输出为10.即使我将代码更改为:
,我得到相同的输出foo=Foo()
foo.__bar=10
print(foo.__bar)
有人可以解释为什么我这里没有收到错误吗?另外我该怎么做才能得到错误? 编辑进一步澄清:
class Foo:
def __init__(self):
self.__bar=10
def get_bar(self):
return self.__bar
foo=Foo()
foo.__bar=20
print(foo.__bar)
print(foo.get_bar())
有人可以解释为什么我得到20和10的答案吗?我以为在尝试访问类外的私有实例变量时会出错。谢谢你的帮助。
答案 0 :(得分:4)
首先,你应该阅读相关问题的答案。
其次,不要在类成员和实例成员之间混淆。您对类Foo
的定义包括一个名为__bar
的类成员,但是分配给foo.__bar
会添加一个 instance-member ,它会遮盖它(而不是覆盖它) 。那些是不同的东西。
现在,当您从“外部”(在您的示例中使用foo.__bar
)分配(或一般来说,访问)前导双下划线属性时,名称不会被破坏,并且一切都可以正常运行额外的魔法。但是,访问前导双下划线属性的标准方法来自类的方法(使用self.__bar
),这就是魔术发生的时候。
演示:
class Foo(object): pass
f = Foo()
foo.__bar = 10
foo.__bar
=> 10
foo.__dict__.keys()
=> dict_keys(['__bar'])
class Foo(object):
def __init__(self):
self.__bar = 10
foo = Foo()
foo.__dict__.keys()
=> dict_keys(['_Foo__bar']) # mangaled!
foo.__bar # cannot access from "outside"
=> AttributeError