python变量下划线开头_一日一技:python中下划线在不同位置的作用
在Python的變量名和方法名中,單下劃線和雙下劃線都有各自的含義,有的僅僅是作為約定,用于提示開發人員,而有的則對Python解釋器有特殊含義。
你可能有些疑惑,在Python中變量名和方法名中的單下劃線、雙下劃線到底有什么含義?下面我們就來看看下面五種下劃線模式和命名約定,以及它們各自如何影響Python程序的行為:
- 前置單下劃線:_var
- 后置單下劃線:var_
- 前置雙下劃線:__var
- 前后雙下劃線:__var__
- 單下劃線:_
前置單下劃線:_var
當涉及變量名和方法名時,前置單下劃線只有約定含義。它對于程序員而言是一種提示,Python社區約定好單下劃線表達的是某種意思,其本身并不會影響程序的行為。
前置單下劃線的意思是提示其他程序員,以單下劃線開頭的變量或方法只在內部使用。PEP 8中定義了這個約定(PEP 8是最常用的Python代碼風格指南8),不過,這個約定對Python解釋器并沒有特殊含義,與Java不同,Python在“私有”和“公共”之間并沒有很強的區別。
來看下面的Student類例子:
class Student:def __init__(self):self.name = "Mark"self._age = 18如果實例化這個類并嘗試訪問在__init__構造函數中定義的name和_age屬性,會發生什么情況?
可以看到_age前面的單下劃線并沒有阻止我們訪問變量的值,這是因為Python中的前置單下劃線只是一個公認的約定,至少在涉及變量名和方法名時是這樣的。但是前置下劃線會影響從模塊中導入名稱的方式。假設在一個名為common.py的模塊中有如下代碼:
def func1():return "func1"def _func2():return "func2"現在,如果使用 from common import * 這種方式導入所有名稱,Python不會導入帶有前置單下劃線的名稱,除非在模塊中定義了__all__列表覆蓋了這個行為:
順便說一下,我們應盡量避免使用*號導入,因為這樣就不清楚當前名稱空間中存在哪些名稱了,為了清楚起見,最好堅持使用常規導入方法,與*號導入不同,常規導入不受前置單下劃線命名約定的影響:
后置單下劃線:var_
有時,當某個變量的名稱已被Python語言中的關鍵字占用,如class、def等的名稱不能用作Python中的變量名,在這種情況下可以追加一個下劃線來繞過命名沖突:
用一個后置單下劃線來避免與Python關鍵字的命名沖突是一個約定。PEP 8定義并解釋了這個約定。
前置雙下劃線:__var
前面的兩種下劃線模式只有約定的意義,但使用以雙下劃線開頭的Python類屬性(變量和方法)就不一樣了,雙下劃線前綴會讓Python解釋器重寫屬性名稱,以避免子類中的命名沖突,這也稱為名稱改寫,即解釋器會更改變量的名稱,以便在稍后擴展這個類時避免命名沖突,下面用代碼示例來實驗一下:
class Student:def __init__(self):self.name = "Mark"self._age = 18self.__gender = "男"if __name__ == "__main__":student = Student()print(dir(student))上圖中我們用內置的dir()函數看這個對象的屬性:該函數返回了一個包含對象屬性的列表,在這個列表中嘗試尋找之前的變量名稱name、_age和__gender,你會發現一些有趣的變化,首先,self.name變量沒有改動,在屬性列表中顯示為name,接著,self._age也一樣,在類中顯示為_age,在這種情況下前置下劃線僅僅是一個約定,是對程序員的一個提示,然而self.__gender就不一樣了,在該列表中找不到__gender這個變量,仔細觀察就會看到,這個對象上有一個名為_Student__gender的屬性,這就是Python解釋器應用名稱改寫之后的名稱,是為了防止子類覆蓋這些變量。
名稱改寫也適用于方法名,會影響在類環境中所有以雙下劃線開頭的名稱。
前后雙下劃線:__var__
如果名字前后都使用雙下劃線,則不會發生名稱改寫,前后由雙下劃線包圍的變量不受Python解釋器的影響:
class Student:def __init__(self):self.name = "Mark"self._age = 18self.__gender = "男"self.__score__ = 99if __name__ == "__main__":student = Student()print(dir(student))print(f"score = {student.__score__}")但是前后雙下劃線的名稱在Python中有特殊用途,像__init__這樣的對象構造函數,用來讓對象可調用的__call__函數,都遵循這條規則。
這些雙下劃線方法通常被稱為魔法方法,雙下劃線方法是Python的核心功能,應根據需要使用,但就命名約定而言,最好避免在自己的程序中使用以雙下劃線開頭和結尾的名稱,以避免與Python語言的未來變更發生沖突。
單下劃線:_
按照約定,單下劃線有時用作名稱,來表示變量是臨時的或棄用的,例如下面的循環中并不需要訪問運行的索引,那么可以使用_來表示它只是一個臨時值:
if __name__ == "__main__":for _ in range(5):print("hello world!")在解包表達式中還可使用單下劃線表示一個棄用的變量來忽略特定的值,同樣,這個含義只是一個約定,不會觸發Python解析器中的任何特殊行為,單下劃線只是一個有效的變量名,偶爾用于該目的。
下面的代碼示例中,我將元組解包為單獨的變量,但其中只關注name和score字段的值。可是為了執行解包表達式,我們就必須為元組中的所有值都分配變量,此時 _ 用作占位符變量:
if __name__ == "__main__":student = ("mark", 19, "男", "99分")name, _, _, score = studentprint(f"name = {name}, score = {score}, _ = {_}")除了用作臨時變量之外,_在大多數Python REPL中是一個特殊變量,表示由解釋器計算的上一個表達式的結果,如果正在使用解釋器會話,用下劃線可以方便地獲取先前計算的結果:
如果正在實時構建對象,有單下劃線的話不用事先指定名稱就能與之交互:
總結:
- 前置單下劃線_var:命名約定,用來表示該名稱僅在內部使用。一般對Python解釋器沒有特殊含義(*號導入除外),只能作為對程序員的提示。
- 后置單下劃線var_:命名約定,用于避免與Python關鍵字發生命名沖突。
- 前置雙下劃線__var:在類環境中使用時會觸發名稱改寫,對Python解釋器有特殊含義。
- 前后雙下劃線__var__:表示由Python語言定義的特殊方法。在自定義的屬性中要避免使用這種命名方式。
- 單下劃線_:有時用作臨時或棄用變量的名稱,此外還能表示Python REPL會話中上一個表達式的結果。
總結
以上是生活随笔為你收集整理的python变量下划线开头_一日一技:python中下划线在不同位置的作用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: resource fork, Finde
- 下一篇: websocket python爬虫_p