从类访问私有模块变量 [英] Accesing private module variable from class
问题描述
我正在尝试了解python作用域规则.为此,我尝试从同一模块的类中访问非常私有"变量
I'm trying understand python scope rules. To do this I try access "very private" variable from class in same module
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
.我在规范中找不到关于此的任何信息.那么,为什么它失败了,并且在哪里描述了这种行为?
It fails with NameError
. I can't find anything about that in specification. So, why it fails and where this behavior described?
推荐答案
在类定义中,所有带有双下划线的名称 starting 都被修饰;重写以将类名作为前缀.
Within a class definition, all names starting with double underscores are mangled; rewritten to include the class name as a prefix.
此功能支持在类中将名称标记为私有",并防止其被子类覆盖.请参见标识符文档:
This is a feature to support marking names as 'private' within the class and protect it against being overwritten by subclasses. See the identifiers documentation:
私人名称处理:当在类定义中以文本形式出现的标识符以两个或多个下划线字符开头且不以两个或多个下划线结尾时,则被认为是该类的私有名称.在为专用名称生成代码之前,专用名称会转换为更长的格式.转换将在类名之前插入类名,并删除前导下划线,并插入单个下划线.例如,出现在名为
Ham
的类中的标识符__spam
将转换为_Ham__spam
.此转换独立于使用标识符的句法上下文.如果转换后的名称过长(超过255个字符),则可能会发生实现定义的截断.如果类名仅包含下划线,则不进行任何转换.
Private name mangling: When an identifier that textually occurs in a class definition begins with two or more underscore characters and does not end in two or more underscores, it is considered a private name of that class. Private names are transformed to a longer form before code is generated for them. The transformation inserts the class name, with leading underscores removed and a single underscore inserted, in front of the name. For example, the identifier
__spam
occurring in a class namedHam
will be transformed to_Ham__spam
. This transformation is independent of the syntactical context in which the identifier is used. If the transformed name is extremely long (longer than 255 characters), implementation defined truncation may happen. If the class name consists only of underscores, no transformation is done.
最好不要在模块全局变量上使用双下划线前缀;无需这样做,一个下划线就足以表明该值在模块内部.
Best not use double-underscore prefixes on module globals; there is no need to do so, a single underscore is enough to communicate that the value is internal to the module.
如果您坚持使用这样的值,请创建一个不混乱的别名,或使用globals()[name]
.
If you are stuck with such a value, create an alias that isn't mangled, or use globals()[name]
.
这篇关于从类访问私有模块变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!