从类访问私有模块变量

时间:2014-01-20 14:43:57

标签: python oop python-2.7 private

我正在尝试理解python范围规则。为此,我尝试从同一模块中的类访问“非常私人”变量

bar = "bar"
_bar = "underscore"
__bar = "double underscore"

def foo():
    print bar
    print _bar
    print globals()["__bar"]
    print __bar

class Foo:
    def __init__(self):
        print bar
        print _bar
        print globals()["__bar"]
        print __bar #NameError: global name '_Foo__bar' is not defined

foo()
Foo()

它以NameError失败。我在规范中找不到任何相关内容。那么,为什么它失败了,这种行为描述的地方呢?

1 个答案:

答案 0 :(得分:3)

在类定义中,所有带有双下划线的名称​​以开头都会被破坏;重写以包括类名作为前缀。

这是一项支持在类中将名称标记为“私有”并保护其不被子类覆盖的功能。请参阅identifiers documentation

  

私有名称修改:当在类定义中以文本方式出现的标识符以两个或多个下划线字符开头且不以两个或多个下划线结尾时,它被视为该类的私有名称。在为其生成代码之前,将私有名称转换为更长的形式。转换将在名称前面插入类名,删除前导下划线并插入单个下划线。例如,名为__spam的类中出现的标识符Ham将转换为_Ham__spam。此转换独立于使用标识符的语法上下文。如果转换后的名称非常长(超过255个字符),则可能会发生实现定义的截断。如果类名仅由下划线组成,则不进行转换。

最好不要在模块全局变量上使用双下划线前缀;没有必要这样做,单个下划线足以表明该值是模块内部的。

如果您遇到这样的值,请创建一个未损坏的别名,或使用globals()[name]