#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())
如果我运行此代码,它将返回 13
我知道解释器应用了名称修饰,所以变量
__x
变成了_test__x
但这与全局变量相同。我尝试使用
self._test__x
但它没有用如何访问
__x
__init __.py
中声明的变量但不是全局变量?
最佳答案
根据 docs,名称修改发生在类主体的任何位置。 :
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 ... This transformation is independent of the syntactical context in which the identifier is used.
教程example表明修饰也发生在类中的属性上。
但真正的问题是您的代码混淆了命名空间。您最初显示的构造函数
def __init__(self, x):
__x = x
创建一个 本地 变量
_test__x
,一旦完成就会被丢弃。要正确分配实例属性:
def __init__(self, x):
self.__x = x
这将创建一个名称实际上是
_test__x
的属性。 .如果你真的想分配全局:
def __init__(self, x):
global __x
__x = x
或者
def __init__(self, x):
global _test__x
__x = x
getter 需要访问实例属性,就像构造函数需要设置它一样。当前版本正在访问全局,因为名称
_tesy__x
本地命名空间中不存在:def rex(self):
return __x
要返回属性,请添加命名空间:
def rex(self):
return self.__x
话虽如此,如果您有一个带有前导双下划线的模块级属性(您不应该这样做),您将很难在类里面访问它。你必须通过
globals
,像这样:globals()['__x']
很久以前我关于这个问题的无耻插件:How to access private variable of Python module from class .
另一个有趣的事实:如果你的类名全是下划线,名字修改就不会发生。您可以通过命名类
_
来逃避所有问题。 , __
, ___
, ____
, ETC。
关于python名称修饰和全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61788707/