來踩 __my_name, __my_name__ 地雷 - tsungjung411/python-study GitHub Wiki
class A:
def __init__(self):
self.__my_name__ = 'A'
def dump_method_info(self):
print("this method is declared at:", self.__my_name__)
class B(A):
def __init__(self):
super(B, self).__init__()
self.__my_name__ = 'B'
b = B()
b.dump_method_info()
print([name for name in dir(b) if 'my_name' in name])
執行結果:
this method is declared at: B
['__my_name__']
預期結果: 應該是顯示 A 才對?怎麽會是 B ?
class A:
def __init__(self):
self.__my_name = 'A'
def dump_method_info(self):
print("this method is declared at:", self.__my_name)
class B(A):
def __init__(self):
super(B, self).__init__()
self.__my_name = 'B'
b = B()
b.dump_method_info()
print([name for name in dir(b) if 'my_name' in name])
執行結果:
this method is declared at: A
['_A__my_name', '_B__my_name']
預期結果: 顯示 A ,符合預期
-
__xxx__
是 Python 特殊用法,給編譯器使用,不建議一般人使用 - 案例A使用
__xxx__
,編譯器「保留」原始名稱,所以子類別在使用時,就會蓋掉父類別的值 - 案例B使用
__xxx
,編譯器針對名稱進行「修改」,讓 A 類別(父類別)有_A_xxx
、 B 類別(子類別)有_B_xxx
,類別A/B不會共用__xxx
,這種編譯手段我們稱為 name magling (名字修飾,又譯作名字粉碎、名字重整)
- 主要目的:解決延伸類別的成員名稱之衝突問題
- 發生情境:如果一個延伸類別,定義一個「跟父類別一樣名稱」的成員,名稱將產生衝突
- Wiki: name magling (名字修飾,又譯作名字粉碎、名字重整)
-
Wiki: Name_mangling#Python
> the mangling only prevents name collisions if a derived class defines a member with the same name.