創(chuàng)新互聯(lián)www.cdcxhl.cn八線(xiàn)動(dòng)態(tài)BGP香港云服務(wù)器提供商,新人活動(dòng)買(mǎi)多久送多久,劃算不套路!
專(zhuān)注于為中小企業(yè)提供成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)甘谷免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千多家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。今天就跟大家聊聊有關(guān)Python中的魔術(shù)方法是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
介紹
在Python中,所有以“__”雙下劃線(xiàn)包起來(lái)的方法,都統(tǒng)稱(chēng)為“Magic Method”,中文稱(chēng)『魔術(shù)方法』,例如類(lèi)的初始化方法 __init__ ,Python中所有的魔術(shù)方法均在官方文檔中有相應(yīng)描述,但是對(duì)于官方的描述比較混亂而且組織比較松散。很難找到有一個(gè)例子。
構(gòu)造和初始化
每個(gè)Pythoner都知道一個(gè)最基本的魔術(shù)方法, __init__ 。通過(guò)此方法我們可以定義一個(gè)對(duì)象的初始操作。然而,當(dāng)調(diào)用 x = SomeClass() 的時(shí)候, __init__ 并不是第一個(gè)被調(diào)用的方法。實(shí)際上,還有一個(gè)叫做__new__ 的方法,兩個(gè)共同構(gòu)成了“構(gòu)造函數(shù)”。
__new__是用來(lái)創(chuàng)建類(lèi)并返回這個(gè)類(lèi)的實(shí)例, 而__init__只是將傳入的參數(shù)來(lái)初始化該實(shí)例。
在對(duì)象生命周期調(diào)用結(jié)束時(shí),__del__ 方法會(huì)被調(diào)用,可以將__del__理解為“構(gòu)析函數(shù)”。下面通過(guò)代碼的看一看這三個(gè)方法:
from os.path import join class FileObject: '''給文件對(duì)象進(jìn)行包裝從而確認(rèn)在刪除時(shí)文件流關(guān)閉''' def __init__(self, filepath='~', filename='sample.txt'): #讀寫(xiě)模式打開(kāi)一個(gè)文件 self.file = open(join(filepath, filename), 'r+') def __del__(self): self.file.close() del self.file
控制屬性訪(fǎng)問(wèn)
許多從其他語(yǔ)言轉(zhuǎn)到Python的人會(huì)抱怨它缺乏類(lèi)的真正封裝。(沒(méi)有辦法定義私有變量,然后定義公共的getter和setter)。Python其實(shí)可以通過(guò)魔術(shù)方法來(lái)完成封裝。我們來(lái)看一下:
__getattr__(self, name):
定義當(dāng)用戶(hù)試圖獲取一個(gè)不存在的屬性時(shí)的行為。這適用于對(duì)普通拼寫(xiě)錯(cuò)誤的獲取和重定向,對(duì)獲取一些不建議的屬性時(shí)候給出警告(如果你愿意你也可以計(jì)算并且給出一個(gè)值)或者處理一個(gè) AttributeError 。只有當(dāng)調(diào)用不存在的屬性的時(shí)候會(huì)被返回。
__setattr__(self, name, value):
與__getattr__(self, name)不同,__setattr__ 是一個(gè)封裝的解決方案。無(wú)論屬性是否存在,它都允許你定義對(duì)對(duì)屬性的賦值行為,以為這你可以對(duì)屬性的值進(jìn)行個(gè)性定制。實(shí)現(xiàn)__setattr__時(shí)要避免"無(wú)限遞歸"的錯(cuò)誤。
__delattr__:
與 __setattr__ 相同,但是功能是刪除一個(gè)屬性而不是設(shè)置他們。實(shí)現(xiàn)時(shí)也要防止無(wú)限遞歸現(xiàn)象發(fā)生。
__getattribute__(self, name):
__getattribute__定義了你的屬性被訪(fǎng)問(wèn)時(shí)的行為,相比較,__getattr__只有該屬性不存在時(shí)才會(huì)起作用。因此,在支持__getattribute__的Python版本,調(diào)用__getattr__前必定會(huì)調(diào)用 __getattribute__。__getattribute__同樣要避免"無(wú)限遞歸"的錯(cuò)誤。需要提醒的是,最好不要嘗試去實(shí)現(xiàn)__getattribute__,因?yàn)楹苌僖?jiàn)到這種做法,而且很容易出bug。
在進(jìn)行屬性訪(fǎng)問(wèn)控制定義的時(shí)候很可能會(huì)很容易引起“無(wú)限遞歸”。如下面代碼:
# 錯(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 # 給類(lèi)中的屬性名分配值 # 定制特有屬性
創(chuàng)建自定義容器
有很多方法可以讓你的Python類(lèi)行為向內(nèi)置容器類(lèi)型一樣,比如我們常用的list、dict、tuple、string等等。Python的容器類(lèi)型分為可變類(lèi)型(如list、dict)和不可變類(lèi)型(如string、tuple),可變?nèi)萜骱筒豢勺內(nèi)萜鞯膮^(qū)別在于,不可變?nèi)萜饕坏┵x值后,不可對(duì)其中的某個(gè)元素進(jìn)行修改。
在講創(chuàng)建自定義容器之前,應(yīng)該先了解下協(xié)議。這里的協(xié)議跟其他語(yǔ)言中所謂的"接口"概念很像,它給你很多你必須定義的方法。然而在Python中的協(xié)議是很不正式的,不需要明確聲明實(shí)現(xiàn)。事實(shí)上,他們更像一種指南。
自定義容器的magic method
下面細(xì)致了解下定義容器可能用到的魔術(shù)方法。首先,實(shí)現(xiàn)不可變?nèi)萜鞯脑?huà),你只能定義 __len__ 和 __getitem__ (下面會(huì)講更多)。可變?nèi)萜鲄f(xié)議則需要所有不可變?nèi)萜鞯乃?,另外還需要 __setitem__ 和 __delitem__ 。如果你希望你的對(duì)象是可迭代的話(huà),你需要定義 __iter__ 會(huì)返回一個(gè)迭代器。迭代器必須遵循迭代器協(xié)議,需要有 __iter__(返回它本身) 和 next。
__len__(self):
返回容器的長(zhǎng)度。對(duì)于可變和不可變?nèi)萜鞯膮f(xié)議,這都是其中的一部分。
__getitem__(self, key):
定義當(dāng)某一項(xiàng)被訪(fǎng)問(wèn)時(shí),使用self[key]所產(chǎn)生的行為。這也是不可變?nèi)萜骱涂勺內(nèi)萜鲄f(xié)議的一部分。如果鍵的類(lèi)型錯(cuò)誤將產(chǎn)生TypeError;如果key沒(méi)有合適的值則產(chǎn)生KeyError。
__setitem__(self, key, value):
當(dāng)你執(zhí)行self[key] = value時(shí),調(diào)用的是該方法。
__delitem__(self, key):
定義當(dāng)一個(gè)項(xiàng)目被刪除時(shí)的行為(比如 del self[key])。這只是可變?nèi)萜鲄f(xié)議中的一部分。當(dāng)使用一個(gè)無(wú)效的鍵時(shí)應(yīng)該拋出適當(dāng)?shù)漠惓!?/p>
__iter__(self):
返回一個(gè)容器迭代器,很多情況下會(huì)返回迭代器,尤其是當(dāng)內(nèi)置的iter()方法被調(diào)用的時(shí)候,以及當(dāng)使用for x in container:方式循環(huán)的時(shí)候。迭代器是它們本身的對(duì)象,它們必須定義返回self的__iter__方法。
__reversed__(self):
實(shí)現(xiàn)當(dāng)reversed()被調(diào)用時(shí)的行為。應(yīng)該返回序列反轉(zhuǎn)后的版本。僅當(dāng)序列可以是有序的時(shí)候?qū)崿F(xiàn)它,例如對(duì)于列表或者元組。
__contains__(self, item):
定義了調(diào)用in和not in來(lái)測(cè)試成員是否存在的時(shí)候所產(chǎn)生的行為。你可能會(huì)問(wèn)為什么這個(gè)不是序列協(xié)議的一部分?因?yàn)楫?dāng)__contains__沒(méi)有被定義的時(shí)候,如果沒(méi)有定義,那么Python會(huì)迭代容器中的元素來(lái)一個(gè)一個(gè)比較,從而決定返回True或者False。
__missing__(self, key):
dict字典類(lèi)型會(huì)有該方法,它定義了key如果在容器中找不到時(shí)觸發(fā)的行為。比如d = {'a': 1}, 當(dāng)你執(zhí)行d[notexist]時(shí),d.__missing__['notexist']就會(huì)被調(diào)用。
看完上述內(nèi)容,你們對(duì)Python中的魔術(shù)方法是什么有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道,感謝大家的支持。
新聞名稱(chēng):Python中的魔術(shù)方法是什么-創(chuàng)新互聯(lián)
本文來(lái)源:http://jinyejixie.com/article28/dijpcp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開(kāi)發(fā)、App開(kāi)發(fā)、外貿(mào)建站、網(wǎng)站營(yíng)銷(xiāo)、品牌網(wǎng)站設(shè)計(jì)、軟件開(kāi)發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容