久久精品国产亚洲高清|精品日韩中文乱码在线|亚洲va中文字幕无码久|伊人久久综合狼伊人久久|亚洲不卡av不卡一区二区|精品久久久久久久蜜臀AV|国产精品19久久久久久不卡|国产男女猛烈视频在线观看麻豆

    1. <style id="76ofp"></style>

      <style id="76ofp"></style>
      <rt id="76ofp"></rt>
      <form id="76ofp"><optgroup id="76ofp"></optgroup></form>
      1. 千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

        手機(jī)站
        千鋒教育

        千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

        千鋒教育

        掃一掃進(jìn)入千鋒手機(jī)站

        領(lǐng)取全套視頻
        千鋒教育

        關(guān)注千鋒學(xué)習(xí)站小程序
        隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

        當(dāng)前位置:首頁(yè)  >  技術(shù)干貨  > Python中的魔術(shù)方法詳解

        Python中的魔術(shù)方法詳解

        來源:千鋒教育
        發(fā)布人:xqq
        時(shí)間: 2023-11-08 02:35:12 1699382112

        Python中,所有以“__”雙下劃線包起來的方法,都統(tǒng)稱為“MagicMethod”,中文稱『魔術(shù)方法』,例如類的初始化方法__init__,Python中所有的魔術(shù)方法均在官方文檔中有相應(yīng)描述,但是對(duì)于官方的描述比較混亂而且組織比較松散。很難找到有一個(gè)例子。

        構(gòu)造和初始化

        每個(gè)Pythoner都知道一個(gè)最基本的魔術(shù)方法,__init__。通過此方法我們可以定義一個(gè)對(duì)象的初始操作。然而,當(dāng)調(diào)用x=SomeClass()的時(shí)候,__init__并不是第一個(gè)被調(diào)用的方法。實(shí)際上,還有一個(gè)叫做__new__的方法,兩個(gè)共同構(gòu)成了“構(gòu)造函數(shù)”。

        __new__是用來創(chuàng)建類并返回這個(gè)類的實(shí)例,而__init__只是將傳入的參數(shù)來初始化該實(shí)例。

        在對(duì)象生命周期調(diào)用結(jié)束時(shí),__del__方法會(huì)被調(diào)用,可以將__del__理解為“構(gòu)析函數(shù)”。下面通過代碼的看一看這三個(gè)方法:

        fromos.pathimportjoin

        classFileObject:

        '''給文件對(duì)象進(jìn)行包裝從而確認(rèn)在刪除時(shí)文件流關(guān)閉'''

        def__init__(self,filepath='~',filename='sample.txt'):

        #讀寫模式打開一個(gè)文件

        self.file=open(join(filepath,filename),'r+')

        def__del__(self):

        self.file.close()

        delself.file

        控制屬性訪問

        許多從其他語言轉(zhuǎn)到Python的人會(huì)抱怨它缺乏類的真正封裝。(沒有辦法定義私有變量,然后定義公共的getter和setter)。Python其實(shí)可以通過魔術(shù)方法來完成封裝。我們來看一下:

        1__getattr__(self,name):

        定義當(dāng)用戶試圖獲取一個(gè)不存在的屬性時(shí)的行為。這適用于對(duì)普通拼寫錯(cuò)誤的獲取和重定向,對(duì)獲取一些不建議的屬性時(shí)候給出警告(如果你愿意你也可以計(jì)算并且給出一個(gè)值)或者處理一個(gè)AttributeError。只有當(dāng)調(diào)用不存在的屬性的時(shí)候會(huì)被返回。

        1__setattr__(self,name,value):

        與__getattr__(self,name)不同,__setattr__是一個(gè)封裝的解決方案。無論屬性是否存在,它都允許你定義對(duì)對(duì)屬性的賦值行為,以為這你可以對(duì)屬性的值進(jìn)行個(gè)性定制。實(shí)現(xiàn)__setattr__時(shí)要避免"無限遞歸"的錯(cuò)誤。

        1__delattr__:

        與__setattr__相同,但是功能是刪除一個(gè)屬性而不是設(shè)置他們。實(shí)現(xiàn)時(shí)也要防止無限遞歸現(xiàn)象發(fā)生。

        1__getattribute__(self,name):

        __getattribute__定義了你的屬性被訪問時(shí)的行為,相比較,__getattr__只有該屬性不存在時(shí)才會(huì)起作用。因此,在支持__getattribute__的Python版本,調(diào)用__getattr__前必定會(huì)調(diào)用__getattribute__。__getattribute__同樣要避免"無限遞歸"的錯(cuò)誤。需要提醒的是,最好不要嘗試去實(shí)現(xiàn)__getattribute__,因?yàn)楹苌僖姷竭@種做法,而且很容易出bug。

        在進(jìn)行屬性訪問控制定義的時(shí)候很可能會(huì)很容易引起“無限遞歸”。如下面代碼:

        #錯(cuò)誤用法

        def__setattr__(self,name,value):

        self.name=value

        #每當(dāng)屬性被賦值的時(shí)候(如self.name=value),__setattr__()會(huì)被調(diào)用,這樣就造成了遞歸調(diào)用。

        #這意味這會(huì)調(diào)用self.__setattr__('name',value),每次方法會(huì)調(diào)用自己。這樣會(huì)造成程序崩潰。

        #正確用法

        def__setattr__(self,name,value):

        self.__dict__[name]=value#給類中的屬性名分配值

        #定制特有屬性

        Python的魔術(shù)方法很強(qiáng)大,但是用時(shí)卻需要慎之又慎,了解正確的使用方法非常重要。

        創(chuàng)建自定義容器

        有很多方法可以讓你的Python類行為向內(nèi)置容器類型一樣,比如我們常用的list、dict、tuple、string等等。Python的容器類型分為可變類型(如list、dict)和不可變類型(如string、tuple),可變?nèi)萜骱筒豢勺內(nèi)萜鞯膮^(qū)別在于,不可變?nèi)萜饕坏┵x值后,不可對(duì)其中的某個(gè)元素進(jìn)行修改。

        在講創(chuàng)建自定義容器之前,應(yīng)該先了解下協(xié)議。這里的協(xié)議跟其他語言中所謂的"接口"概念很像,它給你很多你必須定義的方法。然而在Python中的協(xié)議是很不正式的,不需要明確聲明實(shí)現(xiàn)。事實(shí)上,他們更像一種指南。

        自定義容器的magicmethod

        下面細(xì)致了解下定義容器可能用到的魔術(shù)方法。首先,實(shí)現(xiàn)不可變?nèi)萜鞯脑?,你只能定義__len__和__getitem__(下面會(huì)講更多)。可變?nèi)萜鲄f(xié)議則需要所有不可變?nèi)萜鞯乃?,另外還需要__setitem__和__delitem__。如果你希望你的對(duì)象是可迭代的話,你需要定義__iter__會(huì)返回一個(gè)迭代器。迭代器必須遵循迭代器協(xié)議,需要有__iter__(返回它本身)和next。

        1__len__(self):

        返回容器的長(zhǎng)度。對(duì)于可變和不可變?nèi)萜鞯膮f(xié)議,這都是其中的一部分。

        1__getitem__(self,key):

        定義當(dāng)某一項(xiàng)被訪問時(shí),使用self[key]所產(chǎn)生的行為。這也是不可變?nèi)萜骱涂勺內(nèi)萜鲄f(xié)議的一部分。如果鍵的類型錯(cuò)誤將產(chǎn)生TypeError;如果key沒有合適的值則產(chǎn)生KeyError。

        1__setitem__(self,key,value):

        當(dāng)你執(zhí)行self[key]=value時(shí),調(diào)用的是該方法。

        1__delitem__(self,key):

        定義當(dāng)一個(gè)項(xiàng)目被刪除時(shí)的行為(比如delself[key])。這只是可變?nèi)萜鲄f(xié)議中的一部分。當(dāng)使用一個(gè)無效的鍵時(shí)應(yīng)該拋出適當(dāng)?shù)漠惓!?/p>

        1__iter__(self):

        返回一個(gè)容器迭代器,很多情況下會(huì)返回迭代器,尤其是當(dāng)內(nèi)置的iter()方法被調(diào)用的時(shí)候,以及當(dāng)使用forxincontainer:方式循環(huán)的時(shí)候。迭代器是它們本身的對(duì)象,它們必須定義返回self的__iter__方法。

        1__reversed__(self):

        實(shí)現(xiàn)當(dāng)reversed()被調(diào)用時(shí)的行為。應(yīng)該返回序列反轉(zhuǎn)后的版本。僅當(dāng)序列可以是有序的時(shí)候?qū)崿F(xiàn)它,例如對(duì)于列表或者元組。

        1__contains__(self,item):

        定義了調(diào)用in和notin來測(cè)試成員是否存在的時(shí)候所產(chǎn)生的行為。你可能會(huì)問為什么這個(gè)不是序列協(xié)議的一部分?因?yàn)楫?dāng)__contains__沒有被定義的時(shí)候,如果沒有定義,那么Python會(huì)迭代容器中的元素來一個(gè)一個(gè)比較,從而決定返回True或者False。

        1__missing__(self,key):

        dict字典類型會(huì)有該方法,它定義了key如果在容器中找不到時(shí)觸發(fā)的行為。比如d={'a':1},當(dāng)你執(zhí)行d[notexist]時(shí),d.__missing__['notexist']就會(huì)被調(diào)用。

        以上內(nèi)容為大家介紹了Python中的魔術(shù)方法詳解,希望對(duì)大家有所幫助,如果想要了解更多Python相關(guān)知識(shí),請(qǐng)關(guān)注IT培訓(xùn)機(jī)構(gòu):千鋒教育。

        聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
        10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
        請(qǐng)您保持通訊暢通,專屬學(xué)習(xí)老師24小時(shí)內(nèi)將與您1V1溝通
        免費(fèi)領(lǐng)取
        今日已有369人領(lǐng)取成功
        劉同學(xué) 138****2860 剛剛成功領(lǐng)取
        王同學(xué) 131****2015 剛剛成功領(lǐng)取
        張同學(xué) 133****4652 剛剛成功領(lǐng)取
        李同學(xué) 135****8607 剛剛成功領(lǐng)取
        楊同學(xué) 132****5667 剛剛成功領(lǐng)取
        岳同學(xué) 134****6652 剛剛成功領(lǐng)取
        梁同學(xué) 157****2950 剛剛成功領(lǐng)取
        劉同學(xué) 189****1015 剛剛成功領(lǐng)取
        張同學(xué) 155****4678 剛剛成功領(lǐng)取
        鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
        董同學(xué) 138****2867 剛剛成功領(lǐng)取
        周同學(xué) 136****3602 剛剛成功領(lǐng)取
        相關(guān)推薦HOT
        加查县| 龙胜| 黔江区| 荣昌县| 贵州省| 宝山区| 即墨市| 苏尼特左旗| 洮南市| 多伦县| 兴文县| 河北区| 丰原市| 武城县| 噶尔县| 吉水县| 盘山县| 新泰市| 定安县| 来宾市| 正阳县| 通渭县| 临潭县| 黄平县| 锦屏县| 剑阁县| 赤城县| 桦甸市| 洛南县| 晋中市| 海丰县| 永昌县| 伊金霍洛旗| 大英县| 广德县| 宜川县| 滦南县| 固原市| 绵竹市| 广州市| 平舆县|