从类访问私有模块变量 [英] Accesing private module variable from class

查看:53
本文介绍了从类访问私有模块变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试了解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 named Ham 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆