我正在尝试理解 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
。我在规范中找不到任何相关内容。那么,为什么它会失败以及这种行为在哪里描述?
在类定义中,所有名称starting双下划线被破坏;重写以包含类名作为前缀。
此功能支持在类中将名称标记为“私有”,并防止其被子类覆盖。请参阅标识符文档 http://docs.python.org/2/reference/expressions.html#atom-identifiers:
私人名称修改:当类定义中文本出现的标识符以两个或多个下划线字符开头且不以两个或多个下划线结尾时,它被视为该类的私有名称。在为其生成代码之前,私有名称会转换为更长的形式。该转换将在名称前面插入类名称,删除前导下划线并插入一个下划线。例如,标识符__spam
发生在一个名为Ham
将转变为_Ham__spam
。此转换独立于使用标识符的语法上下文。如果转换后的名称非常长(超过 255 个字符),则可能会发生实现定义的截断。如果类名仅包含下划线,则不进行任何转换。
最好不要在模块全局变量上使用双下划线前缀;没有必要这样做,一个下划线就足以表明该值是模块内部的。
如果您坚持使用这样的值,请创建一个未损坏的别名,或使用globals()[name]
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)