平時寫代碼經常碰到下劃線、雙下劃線等“奇怪”的寫法,今天特意花時間徹底解決這個問題。文章內容主要參考《深入理解Python特性》一書。
 
 
文章目錄 前置單下劃線:_var 后置單下劃線:var_ 前置雙下劃線:__var 前后雙下劃線:__ var__ 單下劃線:_ 總結: 
 
前置單下劃線:_var  
意義:python社區約定好單下劃線 表達的是某種意思,本身不會影響程序的行為 
 
PEP8中定義:以單個下劃線開頭的變量或方法只在內部使用 這個符號對python解釋器沒有什么用,它只是個小小的提示:這個變量或方法并不是這個類的公共接口,最好不要使用它 ——(因為python中沒有嚴格界定“私有”和“公有”變量,因此下劃線可以作為提示) 使用通配符導入模塊 ,Python不會導入帶有前置但下劃線的名稱 ,除非模塊中定義了__all__列表覆蓋了這個行為,舉個例子:  
# test_import.py文件內容
def hello():print('Hello, world!')def _world():print('Hello, world!') 
>>> from test_import import *
>>> hello()
Hello, world!
>>> _world()
Traceback (most recent call last):File "<stdin>", line 1, in <module>
NameError: name '_world' is not defined
 
后置單下劃線:var_  
意義:名稱被Python語言中的關鍵字占用的時候,就可以使用,比如class,def這些,使用class_,def_代替
 
前置雙下劃線:__var  
 這個估計經常遇到
 
 
意義:告訴python解釋器重寫屬性名稱,避免子類中的命名沖突。
 
也稱為:名稱改寫 (name mangling) 用dir()可以查看對象的屬性和方法 注意類似__bar前面雙下劃線的方法和變量,  
class Test:def __init__(self):self.foo = 12self._bar = 24self.__bar = 43
 
class ExtendedTest(Test):def __init__(self):super(ExtendedTest, self).__init__()self.foo = 'hello'self._bar = 'world'self.__bar = 'down'
 
當創建ExtendedTest類的實例t時,調用t.__bar會報錯AttributeError: 'ExtendedTest' object has no attribute '__bar'。
 
>>> dir(t)
['_ExtendedTest__bar', '_Test__bar', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__
', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_bar', 'foo']
 
我們發現t沒有__bar屬性,而是變成了_ExtendedTest__bar和_Test__bar。這是因為Python進行了名稱重寫 。
 
>>> t._ExtendedTest__bar
'down'
>>> t._Test__bar
43
 
我們無法察覺雙下劃線名稱的改寫,也就是我們無法通過t.__bar直接訪問__bar的值,只能借的類方法去訪問或者是通過t._ExtendedTest__bar。類似舉例如下:  
class ManglingTest:def __init__(self):self.__mangled = 'hello'def get_mangled(self):return self.__mangled>>> ManglingTest().get_mangled()
'hello'
>>> ManglingTest().__mangled
AttributeError: "'ManglingTest' object has no attribute '__mangled'"
 
名稱改寫也適用于方法名。  
class MangledMethod:def __method(self):return 42def call_it(self):return self.__method()>>> MangledMethod().__method()
AttributeError: "'MangledMethod' object has no attribute '__method'"
>>> MangledMethod().call_it()
42
 
還有更神奇的用法:由于名稱的改寫,因此類中test()方法用__mangled就可以訪問在MangledGlobal類中訪問全局變量_MangledGlobal__mangled,因為Python的名稱改寫自動擴展了變量名。  
_MangledGlobal__mangled = 23class MangledGlobal:def test(self):return __mangled>>> MangledGlobal().test()
23
 
前后雙下劃線:__ var__  
意義:如果使用前后雙下劃線,那么則不會發生名字重寫,不受python解釋器的影響 。
 
雙下劃線方法稱為魔法方法,最好避免在自己程序中使用雙下劃線開頭和結尾的名稱,避免于python語言未來版本變更發生沖突。 python里面有很多內置方法,如:__hash__,__iter__,__dict__和__repr__等其他內置函數,都是用前后雙下劃線  
單下劃線:_  
表明變量是臨時的或者無關緊要  
for _ in range(10):print('Hello, world! ')
 
表示解釋器計算的上一個表達式的結果  
>>> 20 + 3
23
>>> _
23
>>> print(_)
23>>> list()
[]
>>> _.append(1)
>>> _.append(2)
>>> _.append(3)
>>> _
[1, 2, 3]
 
總結:  
前置單下劃線_var:命名約定 ,表明僅在內部使用(在通配符import * 的時候會有小小的區別),一般對python解釋器沒有特殊的含義 后置單下劃線:var_:命名約定 ,避免與python關鍵字命名沖突 前置雙下劃線:__var:名稱重寫 ,在類環境中使用會觸發名稱改寫,對python解釋器有影響 前后雙下劃線:__var__:python定義的魔法方法 ,在自定義屬性中逼民啊用這種命名方式 單下劃線:_:表明變量是臨時的或者無關緊要 。此外還可以表示Python REPL會話中的上一個結果。  
 結束了…
                            總結 
                            
                                以上是生活随笔 為你收集整理的【Python特性】Python中的下划线和双下划线是什么意思? 的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                            
                                如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。