【问题标题】:No error for Python private variablePython私有变量没有错误
【发布时间】:2015-04-19 01:13:06
【问题描述】:

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

【问题讨论】:

  • 为什么你认为你应该得到一个错误?在你看来,你做错了什么?
  • “私有”变量的下划线只是一个约定。而已。此外,bar__bar 不是同一个属性。 Python 中没有任何内容表明这应该触发任何事情。
  • 哇,这是一个重复。有人解开它吗?
  • 这个问题不是重复的,因为它一般不是询问前导双下划线,而是询问具体用法,并且其他问题中的答案均未涵盖此问题的答案。

标签: python private


【解决方案1】:

首先,您应该阅读相关问题的答案。

其次,不要混淆类成员和实例成员。您对类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

【讨论】:

  • 谢谢@shx2。您能否解释一下“类成员”和“实例变量”是什么意思?你的意思是像Java中的“静态变量”这样的类成员吗?
  • 是的,就像java中的静态变量。
  • 我已经编辑了我的问题以添加一个新场景..你能看看吗?
  • 看看foo.__dict__。这应该说清楚。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-16
  • 1970-01-01
相关资源
最近更新 更多