Python私有变量没有错误

时间:2015-02-18 05:42:46

标签: python private

使用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的答案吗?我以为在尝试访问类外的私有实例变量时会出错。谢谢你的帮助。

1 个答案:

答案 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