python名称混乱和全局变量

python名称混乱和全局变量,python,python-3.x,Python,Python 3.x,如果我运行此代码,它将返回13 我知道解释器应用了名称混乱,因此变量\uuux变成了\utest\uux 但这与全局变量相同 我试图使用self.\u test\uuux,但没有成功 如何访问\uuuux在\uuuu init\uuuuuupy中声明的变量,而不是全局变量?名称损坏在类主体的任何位置都会发生,具体情况如下: 当类定义中以文本形式出现的标识符以两个或多个下划线字符开头,而不是以两个或多个下划线结尾时,它被视为该类的私有名称。。。此转换独立于使用标识符的语法上下文 教程显示,类中的属

如果我运行此代码,它将返回13 我知道解释器应用了名称混乱,因此变量
\uuux
变成了
\utest\uux
但这与全局变量相同

我试图使用self.\u test\uuux,但没有成功


如何访问
\uuuux
\uuuu init\uuuuuupy
中声明的变量,而不是全局变量?

名称损坏在类主体的任何位置都会发生,具体情况如下:

当类定义中以文本形式出现的标识符以两个或多个下划线字符开头,而不是以两个或多个下划线结尾时,它被视为该类的私有名称。。。此转换独立于使用标识符的语法上下文

教程显示,类中的属性也会发生损坏

但真正的问题是,您的代码混淆了名称空间。最初显示的构造函数

#global variable
_test__x=13

class test:
    def __init__(self,x):
        self.__x=x
    def rex(self):
        return __x

d = test(5)
print(d.rex())
创建一个本地变量
\u test\u x
,该变量完成后将被丢弃

要正确分配实例属性,请执行以下操作:

def __init__(self, x):
    __x = x
这将创建一个属性,其名称实际上是
\u test\u x

如果确实要分配全局变量,请执行以下操作:

def __init__(self, x):
    self.__x = x

getter需要访问instance属性,就像构造函数需要设置它一样。当前版本正在访问全局命名空间,因为本地命名空间中不存在名称
\tesy\uuux

def __init__(self, x):
    global _test__x
    __x = x
def rex(self):
    return __x
要返回属性,请添加命名空间:

def __init__(self, x):
    global _test__x
    __x = x
def rex(self):
    return __x
综上所述,如果您有一个带有前导双下划线的模块级属性(您不应该这样做),那么在类中访问它将非常困难。您必须通过
globals
,如下所示:

def rex(self):
    return self.__x
我很久以前就提出了一个关于这一点的无耻的问题:


另一个有趣的事实是:如果您的类名都是下划线,那么名称损坏根本不会发生。您可以通过命名类
。。。现在它只是一个局部变量。我认为这不是你能做到的(至少不容易做到),它不是一个bug,而是一个特性(显然,它实际上是规范的一部分)。见:@bitomic。我没有从那个线程中看到特征部分。这是有文件记录的,但不可否认的是,行为不理智。我试着,但自我。在rex()中,我会写一个答案。在我看来,这是python中最丑陋的事情之一