你看到的是mangling 这个名字。以双下划线开头的名称以特殊方式处理,以避免子类中的名称冲突。
基本上,只要您__some_name
在类中有一个属性,它就会自动重命名_YourClass__some_name
以避免在继承时发生名称冲突。
您可以使用以下dir()
功能进行检查:
>>> class MyClass(object):
... __var = 1
...
>>> dir(MyClass)
['_MyClass__var', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
请注意该列表如何不包含__var
但包含_MyClass__var
.
解决方法很简单:不要使用以双下划线开头的变量名。如果要将变量标记为私有,则约定是使用单个下划线。
我想再次强调,名称修饰的主要目的是避免命名空间与子类发生冲突:
>>> class MyClass(object):
... def __init__(self, val):
... self._value = val
...
>>> class MySubclass(object):
... def __init__(self, val):
... super(MyClass, self).__init__(val)
... self._value = val ** 2 #this hides the base class attribute!
...
请注意,如果基类来自第三方库,那么您无法知道定义了哪些私有属性,因为它们不是 API 的一部分。检查 withdir
只会提示您使用哪个名称,但由于它们是一个实现细节,它们可以在不通知的情况下更改。
您不应该使用它来将属性“标记”为私有。python约定是以单个下划线开头的属性是私有的。
在一个相关主题上,在名称__something__
的开头和结尾都带有双下划线的表单名称也被特殊处理。其中一些实现了特殊方法,因此您永远不应该使用这种标识符。