python class 无法提供 _Secretive__xxx() 功能,为什么?

python class fail to provide _Secretive__xxx() function, why?

我想看看我是否可以调用 python class 的私有函数,我试过 ipython:

In [14]: class C:
   ....:     def __my(s):
   ....:         print "hello"
   ....:       

In [15]: print C
__main__.C

In [16]: obj=C()

In [17]: obj._Secretive__my
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-17-c68d82fedeb4> in <module>()
----> 1 obj._Secretive__my

AttributeError: C instance has no attribute '_Secretive__my'
In [18]: obj._Secretive__my()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-18-ab4a9965f82a> in <module>()
----> 1 obj._Secretive__my()

嗯,看来我不能统计或调用它,对吧?我哪里错了?

方法的名称是 preceded by _ 和 class 名称 (C):

>>> class C:
...   def __my(self):
...     print "hello"
... 
>>> obj = C()
>>> dir(obj)
['_C__my', '__doc__', '__module__']
>>> obj._C__my()
hello

所以,你可以调用这个方法,但是奇怪的命名转换应该让你三思而后行。

实现“Private”实例变量的方式称为 name mangling。请参阅文档 Private Variables and Class-local References

... such a mechanism, called name mangling. Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped.

试试这个:

obj._C__my
obj._C__my()

双下划线前缀名称得到 mangled using the class name - 即 C,在这种情况下:

>>> class C:
...     def __my(self):
...         print('hello')
...         
>>> obj = C()
>>> obj._C__my()
hello

不要使用此功能来尝试并指示方法是 "private"。为此,只需使用一个下划线。名称修改功能是为了防止在一些罕见且复杂的继承情况下发生名称冲突。