【Python基础】关于Python的前后、单双下划线作用
python的各種下劃線(xiàn)
在Python中,可能最常見(jiàn)的就是各種常量、變量、函數(shù)、方法前后添加的那些下劃線(xiàn)了。有前面加的、后面加的,加一個(gè)的,加兩個(gè)的,看到頭暈。那么,你對(duì)這些知識(shí)都掌握了嗎 ?讓我們先來(lái)做一個(gè)自測(cè)吧。
題目:說(shuō)明以下四個(gè)例子輸出的結(jié)果分別是什么。
自測(cè)題各位,請(qǐng)開(kāi)始你的表演,來(lái)看看以上4段代碼分別輸出的結(jié)果是什么?OK,記住你的答案,等看完文章解開(kāi)謎底后,再來(lái)看看的答對(duì)了沒(méi)。
單前導(dǎo)下劃線(xiàn)
單前導(dǎo)下劃線(xiàn)(_xxx),作為Python的命名約定,表示僅供內(nèi)部使用。但注意這個(gè)命名約定,在類(lèi)中你使用單前導(dǎo)線(xiàn)聲明的變量,**依然可以在外部直接訪(fǎng)問(wèn)。**那這種命名約定還有什么意義呢?有!當(dāng)代碼使用
from modlue import *?
導(dǎo)入某個(gè)模塊時(shí),單前導(dǎo)線(xiàn)這種定義方式的屬性,不會(huì)被導(dǎo)入。舉例:
#?demo1.py Name?=?"清風(fēng)" _Age?=?18#?demo2.py from?demo1?import?*print(print(Name,_Age))#output: NameError:?name?'_Age'?is?not?defined??正常的情況是如上結(jié)果,但是萬(wàn)事無(wú)絕對(duì),面試官的陰人考點(diǎn)來(lái)了:
__all__ = ["Name", "_Age"]
當(dāng)demo1.py在開(kāi)頭聲明如上,使用__all__單獨(dú)聲明了可導(dǎo)入內(nèi)容時(shí),可以正常導(dǎo)入。雖然使用起來(lái)矛盾,但是面試陰人必備有木有?
單末尾下劃線(xiàn)
單末尾下劃線(xiàn)(xxx_),按照PEP8規(guī)定,單末尾下劃線(xiàn)也是一個(gè)約定 用來(lái)避免與python關(guān)鍵字產(chǎn)生命名沖突。
例如:我們使用Beautifulsoup進(jìn)行網(wǎng)頁(yè)解析,通過(guò)類(lèi)方法定位時(shí),會(huì)找某個(gè)標(biāo)簽它的存在class=‘xxx’的情況,此時(shí)css的class與Python中的類(lèi)重名,需要在class后添加單下劃線(xiàn)進(jìn)行區(qū)分。類(lèi)似場(chǎng)景還有很多,就不一一列舉了。
雙前導(dǎo)和雙末尾下劃線(xiàn)
日常開(kāi)發(fā)中,最好避免在自己的程序中使用以雙下劃線(xiàn)(“dunders”)開(kāi)頭和結(jié)尾的名稱(chēng),因?yàn)樗荘ython語(yǔ)言定義的一種特殊方法(魔法方法),我們熟知的__init__ 、__dict__ 、__getitem__等等。
但是,如果你非要使用這種寫(xiě)法去聲明,那可真是無(wú)底坑...如果你聲明的變量不是內(nèi)置的魔法方法,Python會(huì)將它當(dāng)做普通的變量來(lái)操作。如果和內(nèi)置的方法重名,要么重寫(xiě),要么因?yàn)楣δ軟_突而引發(fā)報(bào)錯(cuò),所以不作死就不會(huì)死,還是別這么玩了。
雙前導(dǎo)下劃線(xiàn)
這個(gè)為什么放在最后,因?yàn)閴狠S啊!雙前導(dǎo)下劃線(xiàn),在面試中被考到的幾率太大了,尤其是那種長(zhǎng)相猥瑣,心術(shù)不正的面試官,最?lèi)?ài)問(wèn)這個(gè)知識(shí)點(diǎn),所以要牢記。
首先雙前導(dǎo)下劃線(xiàn)(__xxx)的命名,90%情況下是真切的私有變量、方法,剩下10%一會(huì)兒再說(shuō)。下來(lái)說(shuō)說(shuō)雙前導(dǎo)下劃線(xiàn)的作用,既然為私有屬性,那么僅在當(dāng)前類(lèi)中可用,外部、子類(lèi)均無(wú)法調(diào)用和繼承。知道這點(diǎn)寫(xiě)代碼差不多夠了,但還差一點(diǎn),拿文章開(kāi)頭的最后一個(gè)例子來(lái)說(shuō)
#?Test4 class?Root:def?__func(self):print('root')class?Child(Root):def?__init__(self):self.__func()Child()大家剛才的答案是什么,root?恭喜你,打錯(cuò)了,結(jié)果是:
AttributeError: 'Child' object has no attribute '_Child__func'
不該是子類(lèi)沒(méi)有的方法,繼承父類(lèi)么,明明父類(lèi)有,為什么會(huì)報(bào)錯(cuò)。剛才我們說(shuō)到了,雙前導(dǎo)下劃線(xiàn)是真切的私有變量、方法,無(wú)法被子類(lèi)所繼承。如果我們把雙前導(dǎo)下劃線(xiàn),變成了單前導(dǎo)下劃線(xiàn)(如Test3),那么結(jié)果是root。
不能繼承的問(wèn)題明白了,但這個(gè)_Child__func是什么鬼?這就要說(shuō)為什么剛才我說(shuō)雙前導(dǎo)下劃線(xiàn)90%的情況下是真切的私有變量了、讓我們來(lái)看下面的例子:
class?Demo:def?__init__(self):self.__name?=?"清風(fēng)Python"def?__say_hello(self):print(f"你好:{self.__name}")D?=?Demo() #?usually print(D.__name) D.__say_hello#?specially print(D._Demo__name) D._Demo__say_hello()我們定義一個(gè)Demo類(lèi),其中存在雙前導(dǎo)下劃線(xiàn)的__name __say_hello,當(dāng)我們使用通常的調(diào)用方式時(shí),是無(wú)法執(zhí)行的,但Python的私有屬性聲明時(shí),其實(shí)就是將某個(gè)私有屬性前添加單下劃線(xiàn)+類(lèi)名,所以如果其實(shí)不存在什么私有屬性,我們可以通過(guò)_classname__privatefunc的方式實(shí)現(xiàn)強(qiáng)制調(diào)用。
那么,日常中我們能否盡量的避免這種方式呢?方法是有的,但是只能騙騙初學(xué)者,對(duì)有心人還是沒(méi)用,比如:
class?Demo:def?__init__(self):self.__money?=?100@propertydef?money(self):return?self.__money@money.setterdef?money(self,?pwd):passD?=?Demo() D.money?=?1000000 print(D.money)?#?依舊為100塊python的property裝飾器,可以將方法聲明為類(lèi)的屬性,當(dāng)某人調(diào)用D.money得到自己余額為100塊時(shí),肯定想著我重新賦值余額秒變土豪,但真實(shí)的余額我們使用的是私有的self.__money。而通過(guò)property創(chuàng)建了一個(gè)money的屬性,當(dāng)用戶(hù)對(duì)money賦值時(shí),money.setter的方法是空的,你怎么賦值都是無(wú)用的(空的干嘛還要寫(xiě),因?yàn)椴粚?xiě)會(huì)報(bào)錯(cuò)啊...AttributeError: can't set attribute)。
這樣看起來(lái)很完美啊,為什么說(shuō)只能騙騙初學(xué)者?當(dāng)你打印print(D.__dict__)時(shí){'_Demo__money': 100}一目了然。
最后,文章開(kāi)頭的測(cè)試題答案你做對(duì)了么?結(jié)果是:
child、root、root、報(bào)錯(cuò)??你答對(duì)了么?
今天關(guān)于Python中下劃線(xiàn)的內(nèi)容就到此為止,是否起到了穩(wěn)固執(zhí)行的效果呢?如果覺(jué)得有所收獲,歡迎分享給你的小伙伴們一起進(jìn)步啊!
END
往期精彩回顧適合初學(xué)者入門(mén)人工智能的路線(xiàn)及資料下載機(jī)器學(xué)習(xí)及深度學(xué)習(xí)筆記等資料打印機(jī)器學(xué)習(xí)在線(xiàn)手冊(cè)深度學(xué)習(xí)筆記專(zhuān)輯《統(tǒng)計(jì)學(xué)習(xí)方法》的代碼復(fù)現(xiàn)專(zhuān)輯 AI基礎(chǔ)下載機(jī)器學(xué)習(xí)的數(shù)學(xué)基礎(chǔ)專(zhuān)輯 獲取本站知識(shí)星球優(yōu)惠券,復(fù)制鏈接直接打開(kāi): https://t.zsxq.com/qFiUFMV 本站qq群704220115。加入微信群請(qǐng)掃碼:總結(jié)
以上是生活随笔為你收集整理的【Python基础】关于Python的前后、单双下划线作用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【迁移学习】隐私保护下的迁移算法
- 下一篇: 【深度学习】神经网络的Python代码实