Python中類、函數(shù)棒呛、變量名中的下劃線'_'

本文介紹了Python中單下劃線雙下劃線的各種含義和命名約定聂示,名稱修飾(name mangling)的工作原理,以及它如何影響Python類簇秒。

五類下劃線

1鱼喉、 前導(dǎo)單下劃線:_var
2、末尾單下劃線:var_
3趋观、前導(dǎo)雙下劃線:__var
4蒲凶、前導(dǎo)和末尾雙下劃線:__var__
5、單下劃線:_

image.png

1. 單前導(dǎo)下劃線_var

  • 當(dāng)涉及到變量和方法名稱時拆内,單個下劃線前綴有一個約定俗成的含義色冀,它是程序員的一個提示:python社區(qū)一致認(rèn)為它應(yīng)該是什么意思痹届,但不會對程序行為產(chǎn)生影響

  • 告知其他程序員:以單個下劃線開頭的變量或方法僅供內(nèi)部使用(該約定在'PEP 8'中有定義)

  • 不是python的強(qiáng)制規(guī)定。python不像JAVA那樣在"私有"“公有”變量之間存在很強(qiáng)的區(qū)別翻斟。這就像有人用下劃線為標(biāo)識提出一個小小的警告:

“嘿玻褪,這不是真的要成為類的一個公共接口的一部分纵菌。不去管它就好”

class Test:
   def __init__(self):
       self.foo = 11
       self._bar = 23
>>> t = Test()
>>> t.foo
11
>>> t._bar
23

_bar中的前導(dǎo)單下劃線并未阻止我們引用它吻氧。至少相對于變量和方法名而言,前導(dǎo)單下劃線_僅是一個定義內(nèi)部(私有)變量或方法的約定而已融欧。

但是敏弃,前導(dǎo)下劃線的確會影響從模塊中導(dǎo)入名稱的方式。


# This is my_module.py:
 
def external_func():
   return 23
def _internal_func():
   return 42
>>> from my_module import *
>>> external_func()
23
>>> _internal_func()
NameError: "name '_internal_func' is not defined"

此時噪馏,如果使用通配符從模塊中導(dǎo)入所有名稱麦到,則Python不會導(dǎo)入帶有前導(dǎo)下劃線的名稱(除非模塊定義了覆蓋此行為的all列表)。

  • PEP 8推薦避免通配符導(dǎo)入欠肾,如果你遵循此約定瓶颠,那么就不必?fù)?dān)憂上述問題,只需要記状烫摇:

單個下劃線是一個Python命名約定粹淋,表示這個名稱是供內(nèi)部使用的。 它通常不由Python解釋器強(qiáng)制執(zhí)行,僅僅作為一種對程序員的提示桃移。

2屋匕、末尾單下劃線var_

  • 作為一個命名用的字符,用于解決命名沖突借杰。有時候过吻,一個變量的最合適的名稱已經(jīng)被一個關(guān)鍵字所占用。 因此第步,像class或def這樣的名稱不能用作Python中的變量名稱疮装。 在這種情況下缘琅,你可以附加一個下劃線來解決命名沖突:

3粘都、前導(dǎo)雙下劃線__var

  • 雙下劃線前綴會導(dǎo)致Python解釋器重寫屬性名稱,以避免子類中的命名沖突刷袍。
    這也叫做名稱修飾(name mangling) —— 解釋器更改變量的名稱翩隧,以便在類被擴(kuò)展的時候不容易產(chǎn)生沖突。
class Test:
   def __init__(self):
       self.foo = 11
       self._bar = 23
       self.__baz = 23
>>> t = Test()
>>> dir(t)
['_Test__baz', '__class__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'__weakref__', '_bar', 'foo']

可以看見:

self.foo變量在屬性列表中顯示為未修改為foo呻纹。
self._bar經(jīng)解釋器解釋后并無變化堆生。
self.__baz情況看起來有點不同,它被解釋器做了名稱修飾雷酪,變?yōu)榱?code>_Test__baz

class ExtendedTest(Test):
   def __init__(self):
       super().__init__()
       self.foo = 'overridden'
       self._bar = 'overridden'
       self.__baz = 'overridden'
>>> t2 = ExtendedTest()
>>> t2.foo
'overridden'
>>> t2._bar
'overridden'
>>> t2.__baz
AttributeError: "'ExtendedTest' object has no attribute '__baz'"

直接使用__baz引用該屬性(或方法)就出錯了淑仆。而得如下方式才能引用:

>>> t2._Test__baz
42

4、前導(dǎo)和末尾雙下劃線__var__

  • 與前導(dǎo)雙下劃線__var不同哥力,在解釋器解釋過程中蔗怠,前導(dǎo)和末尾雙下劃線__var__不會應(yīng)用名稱修飾。
class PrefixPostfixTest:
   def __init__(self):
       self.__bam__ = 42
 
>>> PrefixPostfixTest().__bam__
42
  • 但是吩跋,Python保留了有雙前導(dǎo)和雙末尾下劃線的名稱寞射,用于特殊用途。 這樣的例子有锌钮,__init__對象構(gòu)造函數(shù)桥温,或__call__它使得一個對象可以被調(diào)用。

  • 這些dunder方法通常被稱為神奇方法 梁丘, 但Python社區(qū)中的許多人(包括我自己)都不喜歡這種方法侵浸。

  • 最好避免在自己的程序中使用以雙下劃線(dunders)開頭和結(jié)尾的名稱,以避免與將來Python語言的變化產(chǎn)生沖突氛谜。

5通惫、單下劃線 _

  • 按照習(xí)慣,有時候單個獨立下劃線_用作一個名字混蔼,來表示某個變量是臨時的或無關(guān)緊要的履腋。
>>> for _ in range(32):
...    print('Hello, World.')

在上述代碼段中,單下劃線_僅作為一個臨時變量用于循環(huán)迭代。

  • 在拆分(unpacking)表達(dá)式中將單個下劃線用作“不關(guān)心的”變量遵湖,以忽略特定的值悔政。
  • 這個含義只是“依照約定”,并不會在Python解釋器中觸發(fā)特殊的行為延旧。 單個下劃線僅僅是一個有效的變量名稱谋国,會有這個用途而已。
>>> car = ('red', 'auto', 12, 3812.4)
>>> color, _, _, mileage = car
 
>>> color
'red'
>>> mileage
3812.4
>>> _
12

上述代碼段中迁沫,_作為占位符變量使用芦瘾。

  • 除了用作臨時變量之外,_是大多數(shù)Python REPL中的一個特殊變量集畅,它表示由解釋器評估的最近一個表達(dá)式的結(jié)果近弟。

這樣就很方便了,比如你可以在一個解釋器會話中訪問先前計算的結(jié)果挺智,或者祷愉,你是在動態(tài)構(gòu)建多個對象并與它們交互,無需事先給這些對象分配名字:

>>> 20 + 3
23
>>> _
23
>>> print(_)
23
 
>>> list()
[]
>>> _.append(1)
>>> _.append(2)
>>> _.append(3)
>>> _
[1, 2, 3]

改寫自:https://blog.csdn.net/tcx1992
原文作者:地球的外星人君
鏈接:https://zhuanlan.zhihu.com/p/36173202
著作權(quán)歸作者所有赦颇。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)二鳄,非商業(yè)轉(zhuǎn)載請注明出處。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末媒怯,一起剝皮案震驚了整個濱河市订讼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌扇苞,老刑警劉巖欺殿,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異杨拐,居然都是意外死亡祈餐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門哄陶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來帆阳,“玉大人,你說我怎么就攤上這事屋吨⊙寻” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵至扰,是天一觀的道長鳍徽。 經(jīng)常有香客問我,道長敢课,這世上最難降的妖魔是什么阶祭? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任绷杜,我火速辦了婚禮,結(jié)果婚禮上濒募,老公的妹妹穿的比我還像新娘鞭盟。我一直安慰自己,他們只是感情好瑰剃,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布齿诉。 她就那樣靜靜地躺著,像睡著了一般晌姚。 火紅的嫁衣襯著肌膚如雪粤剧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天挥唠,我揣著相機(jī)與錄音抵恋,去河邊找鬼。 笑死猛遍,一個胖子當(dāng)著我的面吹牛馋记,可吹牛的內(nèi)容都是我干的号坡。 我是一名探鬼主播懊烤,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼宽堆!你這毒婦竟也來了腌紧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤畜隶,失蹤者是張志新(化名)和其女友劉穎壁肋,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體籽慢,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡浸遗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了箱亿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跛锌。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖届惋,靈堂內(nèi)的尸體忽然破棺而出髓帽,到底是詐尸還是另有隱情,我是刑警寧澤脑豹,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布郑藏,位于F島的核電站,受9級特大地震影響瘩欺,放射性物質(zhì)發(fā)生泄漏必盖。R本人自食惡果不足惜拌牲,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望歌粥。 院中可真熱鬧们拙,春花似錦、人聲如沸阁吝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽突勇。三九已至装盯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間甲馋,已是汗流浹背埂奈。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留定躏,地道東北人账磺。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像痊远,于是被迫代替她去往敵國和親垮抗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354