name mangling
在官方文档中的描述
Any identifier of the form
__spam
(at least two leading underscores, at most one trailing underscore) is textually replaced with_classname__spam
, whereclassname
is the current class name with leading underscore(s) stripped.
即在类定义中,以两个及其以上下划线开头且以一个以内下划线结束的命名的任意标识符 _spam
,都会被逐字替换后加上其类名,变成_classname_spam
。
使用技巧
Trick 1: 私有变量的实现
“Private” instance variables that cannot be accessed except from inside an object don’t exist in Python.
python 中不存在 “私有” 的概念,执行语句是按照 namespace 的变量搜索顺序查找变量并对变量进行访问操作。结合 name mangling
机制,可以实现 “伪私有”。 如下
1 | class A: |
即通过 name mangling
的自动替换,类中将不存在任意以双下划线开头的属性,使得上面 demo 中 o
不能访问 __j
,因为实际上,在 python
的 namespace
中不存在 __j
,而是 _A__j
。
注意 name mangling
之作用于类定义,故在 if_main
中的编码 print(o.__j)
不会被自动替换。
Trick 2: 阻止类方法覆盖
python
官方文档中也有同样的例子
1 | class A: |
output :
1 | call A.bar |
A.bar
函数中的 self.bar()
是动态调用,具有 C++
中虚函数的效果,而 __foo
属性通过 name mangling
机制的自动替换,可以实现对 A.foo
的硬编码,防止继承覆写函数的动态调用。