为什么 python 在这里处理
Why is python mangling here
如果没有 cls,为什么这段代码会失败。在 __TEXT
之前
__TEXT = "abcde"
print(__TEXT)
class aaa():
@classmethod
def bbb(cls):
print(__TEXT)
aaa.bbb()
输出为:
abcde
Traceback (most recent call last):
File "<string>", line 9, in <module>
File "<string>", line 7, in bbb
NameError: name '_aaa__TEXT' is not defined
如果您将 __TEXT 设为 class 变量并尝试在不使用 class 前缀的情况下引用它,如下所示:
class aaa():
__TEXT = "abcde"
@classmethod
def bbb(cls):
print(cls.__TEXT)
print(__TEXT)
x = aaa()
x.bbb()
你得到同样的错误,但它没有意义:
abcde
Traceback (most recent call last):
File "<string>", line 10, in <module>
File "<string>", line 7, in bbb
NameError: name '_aaa__TEXT' is not defined
不太确定这是否是错误,但您可以让该函数需要一个参数文本,这似乎工作得很好。不过您需要提供更多信息,以便我尽力提供帮助。
__TEXT = "abcde"
print(__TEXT)
class aaa():
@classmethod
def bbb(self, __TEXT):
print(__TEXT)
aaa.bbb(__TEXT)
双下划线前缀导致 Python 解释器重写属性名称以避免子classes 中的命名冲突。
这也称为“名称修改”。解释器更改变量名称的方式使得在 class 稍后扩展时更难产生冲突。
参考文档:https://docs.python.org/3/tutorial/classes.html#private-variables
在PEP 8中,他们明确表示:
__double_leading_underscore: when naming a class attribute, invokes name mangling (inside class FooBar, __boo becomes _FooBar__boo ...).
注意以粗体显示的选择。在他们提请注意 mangling 在命名 class 属性时使用的完全相同的句子中,他们指出 mangling 发生在 classany __boo
内部=],这完美地解释了您正在观察的内容。
Python 解释器 mangles variable-names 与 double-underscore 避免 名称与子类 .
定义的 variable-names 冲突
这背后的目标几乎等同于 Java 中的最终变量和 C++ 中的非虚拟变量。
举个例子:
class Human:
def __init__(self):
self.surname = 'Jeffrey'
self._age = 22
self.__id = 5
# Let's check the variables associated with this class
x = Human()
print(dir(x)) # gives: ['_Human__id', ..., '_age', 'name']
# Create a subclass 'Cook'
class Cook(Human):
def __init__(self):
Human.__init__(self)
self.__id = 25
y = Cook()
print(dir(y)) # gives: ['_Human__id', '_Cook__id', ..., '_age', 'name']
如果没有 cls,为什么这段代码会失败。在 __TEXT
之前__TEXT = "abcde"
print(__TEXT)
class aaa():
@classmethod
def bbb(cls):
print(__TEXT)
aaa.bbb()
输出为:
abcde
Traceback (most recent call last):
File "<string>", line 9, in <module>
File "<string>", line 7, in bbb
NameError: name '_aaa__TEXT' is not defined
如果您将 __TEXT 设为 class 变量并尝试在不使用 class 前缀的情况下引用它,如下所示:
class aaa():
__TEXT = "abcde"
@classmethod
def bbb(cls):
print(cls.__TEXT)
print(__TEXT)
x = aaa()
x.bbb()
你得到同样的错误,但它没有意义:
abcde
Traceback (most recent call last):
File "<string>", line 10, in <module>
File "<string>", line 7, in bbb
NameError: name '_aaa__TEXT' is not defined
不太确定这是否是错误,但您可以让该函数需要一个参数文本,这似乎工作得很好。不过您需要提供更多信息,以便我尽力提供帮助。
__TEXT = "abcde"
print(__TEXT)
class aaa():
@classmethod
def bbb(self, __TEXT):
print(__TEXT)
aaa.bbb(__TEXT)
双下划线前缀导致 Python 解释器重写属性名称以避免子classes 中的命名冲突。
这也称为“名称修改”。解释器更改变量名称的方式使得在 class 稍后扩展时更难产生冲突。
参考文档:https://docs.python.org/3/tutorial/classes.html#private-variables
在PEP 8中,他们明确表示:
__double_leading_underscore: when naming a class attribute, invokes name mangling (inside class FooBar, __boo becomes _FooBar__boo ...).
注意以粗体显示的选择。在他们提请注意 mangling 在命名 class 属性时使用的完全相同的句子中,他们指出 mangling 发生在 classany __boo
内部=],这完美地解释了您正在观察的内容。
Python 解释器 mangles variable-names 与 double-underscore 避免 名称与子类 .
定义的 variable-names 冲突这背后的目标几乎等同于 Java 中的最终变量和 C++ 中的非虚拟变量。
举个例子:
class Human:
def __init__(self):
self.surname = 'Jeffrey'
self._age = 22
self.__id = 5
# Let's check the variables associated with this class
x = Human()
print(dir(x)) # gives: ['_Human__id', ..., '_age', 'name']
# Create a subclass 'Cook'
class Cook(Human):
def __init__(self):
Human.__init__(self)
self.__id = 25
y = Cook()
print(dir(y)) # gives: ['_Human__id', '_Cook__id', ..., '_age', 'name']