來踩 __my_name, __my_name__ 地雷 - tsungjung411/python-study GitHub Wiki

案例A:變數前後,使用兩個底線(double leading and trailing underscores)

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 ?

   


案例B:變數前,使用兩個底線(double leading underscores)

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 (名字修飾,又譯作名字粉碎、名字重整)

 

延伸閱讀

 

關於 Name mangling

⚠️ **GitHub.com Fallback** ⚠️