Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从类中访问私有模块变量_Python_Oop_Python 2.7_Private - Fatal编程技术网

Python 从类中访问私有模块变量

Python 从类中访问私有模块变量,python,oop,python-2.7,private,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

我正在努力理解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()

它失败,出现
namererror
。我在说明书中找不到任何关于这个的东西。那么,为什么它失败了,这种行为在哪里描述

在类定义中,所有以双下划线开头的名称都被损坏;重写以包含类名作为前缀

这是一个支持在类中将名称标记为“private”并防止其被子类覆盖的功能。见:

私有名称混乱:当类定义中以文本形式出现的标识符以两个或多个下划线字符开头,而不是以两个或多个下划线结尾时,它被视为该类的私有名称。在为私有名称生成代码之前,会将其转换为更长的形式。转换将在名称前面插入类名,删除前导下划线并插入一个下划线。例如,出现在名为
Ham
的类中的标识符
\uuu spam
将转换为
\uham\uu spam
。此转换独立于使用标识符的语法上下文。如果转换后的名称非常长(超过255个字符),则可能会发生实现定义的截断。如果类名只包含下划线,则不进行任何转换

最好不要在模块全局变量上使用双下划线前缀;不需要这样做,一个下划线就足以说明该值是模块内部的


如果您一直使用这样的值,请创建一个没有损坏的别名,或者在类定义中使用
globals()[name]
,所有以双下划线开头的名称都会损坏;重写以包含类名作为前缀

这是一个支持在类中将名称标记为“private”并防止其被子类覆盖的功能。见:

私有名称混乱:当类定义中以文本形式出现的标识符以两个或多个下划线字符开头,而不是以两个或多个下划线结尾时,它被视为该类的私有名称。在为私有名称生成代码之前,会将其转换为更长的形式。转换将在名称前面插入类名,删除前导下划线并插入一个下划线。例如,出现在名为
Ham
的类中的标识符
\uuu spam
将转换为
\uham\uu spam
。此转换独立于使用标识符的语法上下文。如果转换后的名称非常长(超过255个字符),则可能会发生实现定义的截断。如果类名只包含下划线,则不进行任何转换

最好不要在模块全局变量上使用双下划线前缀;不需要这样做,一个下划线就足以说明该值是模块内部的


如果您被这样的值困扰,请创建一个没有损坏的别名,或者使用
globals()[name]

您能发布完整的输出吗?还是完整的异常消息?是的,被删除了,因为——正如我惊讶地发现的那样——即使使用独立名称
\uu bar
,也会发生这种情况。您从文档中发布的引用并没有明确地说明这一点。@DanielRoseman:当一个标识符以文本形式出现在类定义中,并且该转换独立于使用该标识符的语法上下文时。这包括在类主体中任何位置作为标识符的任何内容,包括方法定义。不管它是属性、全局还是局部。你能发布完整的输出吗?还是完整的异常消息?是的,被删除了,因为——正如我惊讶地发现的那样——即使使用独立名称
\uu bar
,也会发生这种情况。您从文档中发布的引用并没有明确地说明这一点。@DanielRoseman:当一个标识符以文本形式出现在类定义中,并且该转换独立于使用该标识符的语法上下文时。这包括在类主体中任何位置作为标识符的任何内容,包括方法定义。不管它是一个属性、一个全局的还是一个局部的,那么如何从类内部访问一个双精度常数呢
globals()。。。最好不要使用双下划线名称作为全局变量,真的。是的,我就是这么想的:)那么从类内部访问双下划线常量的最佳方法是什么呢
globals()。。。最好不要使用双下划线作为全局名称,真的。是的,我就是这么想的:)