<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          關(guān)于Python的前后、單雙下劃線作用,看完這篇文章,吊打面試官!

          共 3035字,需瀏覽 7分鐘

           ·

          2020-09-16 03:11

          點擊上方AI算法與圖像處理”,選擇加"星標"或“置頂”

          重磅干貨,第一時間送達

          來源:清風python

          python的各種下劃線

          在Python中,可能最常見的就是各種常量、變量、函數(shù)、方法前后添加的那些下劃線了。有前面加的、后面加的,加一個的,加兩個的,看到頭暈。那么,你對這些知識都掌握了嗎 ?讓我們先來做一個自測吧。

          題目:說明以下四個例子輸出的結(jié)果分別是什么。

          自測題

          各位,請開始你的表演,來看看以上4段代碼分別輸出的結(jié)果是什么?OK,記住你的答案,等看完文章解開謎底后,再來看看的答對了沒。


          單前導(dǎo)下劃線


          單前導(dǎo)下劃線(_xxx),作為Python的命名約定,表示僅供內(nèi)部使用。但注意這個命名約定,在類中你使用單前導(dǎo)線聲明的變量,**依然可以在外部直接訪問。**那這種命名約定還有什么意義呢?有!當代碼使用

          from modlue import *?

          導(dǎo)入某個模塊時,單前導(dǎo)線這種定義方式的屬性,不會被導(dǎo)入。舉例:

          #?demo1.py
          Name?=?"清風"
          _Age?=?18

          #?demo2.py
          from?demo1?import?*

          print(print(Name,_Age))

          #output:
          NameError:?name?'_Age'?is?not?defined??

          正常的情況是如上結(jié)果,但是萬事無絕對,面試官的陰人考點來了:

          __all__ = ["Name", "_Age"]

          demo1.py在開頭聲明如上,使用__all__單獨聲明了可導(dǎo)入內(nèi)容時,可以正常導(dǎo)入。雖然使用起來矛盾,但是面試陰人必備有木有?


          單末尾下劃線


          單末尾下劃線(xxx_),按照PEP8規(guī)定,單末尾下劃線也是一個約定 用來避免與python關(guān)鍵字產(chǎn)生命名沖突。

          例如:我們使用Beautifulsoup進行網(wǎng)頁解析,通過類方法定位時,會找某個標簽它的存在class=‘xxx’的情況,此時css的class與Python中的類重名,需要在class后添加單下劃線進行區(qū)分。類似場景還有很多,就不一一列舉了。


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


          日常開發(fā)中,最好避免在自己的程序中使用以雙下劃線(“dunders”)開頭和結(jié)尾的名稱,因為它是Python語言定義的一種特殊方法(魔法方法),我們熟知的__init__ 、__dict__ 、__getitem__等等。

          但是,如果你非要使用這種寫法去聲明,那可真是無底坑...如果你聲明的變量不是內(nèi)置的魔法方法,Python會將它當做普通的變量來操作。如果和內(nèi)置的方法重名,要么重寫,要么因為功能沖突而引發(fā)報錯,所以不作死就不會死,還是別這么玩了。


          雙前導(dǎo)下劃線


          這個為什么放在最后,因為壓軸啊!雙前導(dǎo)下劃線,在面試中被考到的幾率太大了,尤其是那種長相猥瑣,心術(shù)不正的面試官,最愛問這個知識點,所以要牢記。

          首先雙前導(dǎo)下劃線(__xxx)的命名,90%情況下是真切的私有變量、方法,剩下10%一會兒再說。下來說說雙前導(dǎo)下劃線的作用,既然為私有屬性,那么僅在當前類中可用,外部、子類均無法調(diào)用和繼承。知道這點寫代碼差不多夠了,但還差一點,拿文章開頭的最后一個例子來說

          #?Test4
          class?Root:
          ????def?__func(self):
          ????????print('root')

          class?Child(Root):
          ????def?__init__(self):
          ????????self.__func()

          Child()

          大家剛才的答案是什么,root?恭喜你,打錯了,結(jié)果是:

          AttributeError: 'Child' object has no attribute '_Child__func'

          不該是子類沒有的方法,繼承父類么,明明父類有,為什么會報錯。剛才我們說到了,雙前導(dǎo)下劃線是真切的私有變量、方法,無法被子類所繼承。如果我們把雙前導(dǎo)下劃線,變成了單前導(dǎo)下劃線(如Test3),那么結(jié)果是root。

          不能繼承的問題明白了,但這個_Child__func是什么鬼?這就要說為什么剛才我說雙前導(dǎo)下劃線90%的情況下是真切的私有變量了、讓我們來看下面的例子:

          class?Demo:
          ????def?__init__(self):
          ????????self.__name?=?"清風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()

          我們定義一個Demo類,其中存在雙前導(dǎo)下劃線的__name __say_hello,當我們使用通常的調(diào)用方式時,是無法執(zhí)行的,但Python的私有屬性聲明時,其實就是將某個私有屬性前添加單下劃線+類名,所以如果其實不存在什么私有屬性,我們可以通過_classname__privatefunc的方式實現(xiàn)強制調(diào)用。

          那么,日常中我們能否盡量的避免這種方式呢?方法是有的,但是只能騙騙初學者,對有心人還是沒用,比如:

          class?Demo:
          ????def?__init__(self):
          ????????self.__money?=?100

          ????@property
          ????def?money(self):
          ????????return?self.__money
          ????
          [email protected]
          ????def?money(self,?pwd):
          ????????pass
          ????
          D?=?Demo()
          D.money?=?1000000
          print(D.money)?#?依舊為100塊

          python的property裝飾器,可以將方法聲明為類的屬性,當某人調(diào)用D.money得到自己余額為100塊時,肯定想著我重新賦值余額秒變土豪,但真實的余額我們使用的是私有的self.__money。而通過property創(chuàng)建了一個money的屬性,當用戶對money賦值時,money.setter的方法是空的,你怎么賦值都是無用的(空的干嘛還要寫,因為不寫會報錯啊...AttributeError: can't set attribute)。

          這樣看起來很完美啊,為什么說只能騙騙初學者?當你打印print(D.__dict__){'_Demo__money': 100}一目了然。

          最后,文章開頭的測試題答案你做對了么?結(jié)果是:

          child、root、root、報錯??你答對了么?

          今天關(guān)于Python中下劃線的內(nèi)容就到此為止,是否起到了穩(wěn)固執(zhí)行的效果呢?如果覺得有所收獲,歡迎分享給你的小伙伴們一起進步啊!

          END


          下載1:動手學深度學習


          AI算法與圖像處公眾號后臺回復(fù):OpenCV黑魔法,即可下載小編精心編寫整理的計算機視覺趣味實戰(zhàn)教程


          下載2
          AI算法與圖像處公眾號后臺回復(fù):CVPR2020即可下載1467篇CVPR?2020論文
          個人微信(如果沒有備注不拉群!
          請注明:地區(qū)+學校/企業(yè)+研究方向+昵稱

          瀏覽 46
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美日本操逼网站 | 狠狠狠干 | 操逼首页123 | 国产最新地址 | 亚洲无码成人在线 |