精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Python神奇方法系統(tǒng)的梳理

DPVg_AI_era ? 來(lái)源:未知 ? 作者:李倩 ? 2018-08-15 08:18 ? 次閱讀

Python神奇方法是指一些允許在自定義類中增加“神奇”功能的方法。而在Python官方文檔中,有關(guān)這些方法的介紹或描述不僅內(nèi)容分散,而且組織結(jié)構(gòu)也相對(duì)松散。本文便對(duì)Python神奇方法做了系統(tǒng)的梳理。對(duì)于初學(xué)者亦或Python行家,都或多或少的會(huì)有些幫助。

話不多說(shuō),直接進(jìn)入主題!

Python神奇指南目錄

簡(jiǎn)介

搭建與初始化

在自定義類中運(yùn)用操作符

神奇方法比較

神奇方法數(shù)字

描述自定義類

控制屬性訪問(wèn)

制作自定義序列

反射

可調(diào)用對(duì)象

上下文管理器

構(gòu)建描述符對(duì)象

簡(jiǎn)介

何為神奇方法呢?它們是面向Python中的一切,是一些特殊的方法允許在自己的定義類中定義增加“神奇”的功能。它們總是使用雙下劃線(比如__init__或__lt__),但它們的文檔沒(méi)有很好地把它們表現(xiàn)出來(lái)。所有這些神奇方法都出現(xiàn)在Python的官方文檔中,但內(nèi)容相對(duì)分散,組織結(jié)構(gòu)也顯得松散。還有你會(huì)難以發(fā)現(xiàn)一個(gè)實(shí)例(雖然他們被設(shè)計(jì)很棒,在語(yǔ)言參考中被詳細(xì)描述,可之后就會(huì)伴隨著枯燥的語(yǔ)法描述等)。

為了彌補(bǔ)Python官方文檔的這些缺陷,作者整理了這篇有關(guān)magic method的文章,旨在用作教程、復(fù)習(xí)或參考文檔。

搭建與初始化

相信大家都熟悉這個(gè)最基礎(chǔ)的神奇方法__init__。它令你能自定義一個(gè)對(duì)象的初始化行為。而當(dāng)我調(diào)用x=SomeClass()時(shí),__init__并不是最先被調(diào)用的。實(shí)際上有一個(gè)叫做__new__的方法,事實(shí)上是它創(chuàng)建了實(shí)例,它傳遞任何參數(shù)給初始化程序來(lái)達(dá)到創(chuàng)建的目的。在對(duì)象生命周期結(jié)束時(shí),調(diào)用__del__。讓我們更近地觀察下這3個(gè)神奇方法吧:

__new__(cls,[…)

一個(gè)對(duì)象的實(shí)例化時(shí)__new__是第一個(gè)被調(diào)用的方法。在類中傳遞其他任何參數(shù)到__init__。__new__很少被使用,這樣做確實(shí)有其目的,特別是當(dāng)一個(gè)子類繼承一個(gè)不可改變的類型(一個(gè)元組或一個(gè)字符串)時(shí)。

__init__(self,[…)

類的初始化。創(chuàng)建對(duì)象后,python解釋器默認(rèn)調(diào)用__init__()方法。無(wú)論主構(gòu)造函數(shù)調(diào)用什么,它都會(huì)被傳遞。__init__幾乎在Python類定義中普遍使用。

__del__(self)

如果__new__和__init__構(gòu)成了對(duì)象的構(gòu)造函數(shù),__ del__就是析構(gòu)函數(shù)。當(dāng)刪除一個(gè)對(duì)象時(shí),python解釋器也會(huì)默認(rèn)調(diào)用__del__()方法。在python中,對(duì)于開(kāi)發(fā)者來(lái)說(shuō)很少會(huì)直接銷毀對(duì)象(如果需要,應(yīng)該使用del關(guān)鍵字銷毀)。Python的內(nèi)存管理機(jī)制能夠很好的勝任這份工作。也就是說(shuō),不管是手動(dòng)調(diào)用del還是由python自動(dòng)回收都會(huì)觸發(fā)__del__方法執(zhí)行。

如下,是是__init__和__del__的例子:

fromos.pathimportjoinclassFileObject:'''對(duì)文件對(duì)象的包裝,確保文件在關(guān)閉時(shí)得到刪除'''def__init__(self,filepath='~',filename='sample.txt'):#按filepath,讀寫(xiě)模式打開(kāi)名為filename的文件self.file=open(join(filepath,filename),'r+')def__del__(self):self.file.close()delself.file

在自定義類中運(yùn)用操作符

神奇方法比較:

Python有一大堆magic method,旨在使用運(yùn)算符實(shí)現(xiàn)對(duì)象之間的直觀比較,而非別扭的方法調(diào)用。它們還提供了一種方法來(lái)覆蓋用于對(duì)象比較的默認(rèn)Python行為。下面是這些方法的列表以及它們的作用:

__cmp__(self,other)

__cmp__是神奇方法中最基礎(chǔ)的一個(gè)。實(shí)際上它實(shí)現(xiàn)所有比較操作符行為(<,==,!=,等),但它有可能不按你想要的方法工作(例如,一個(gè)實(shí)例是否等于另一個(gè)這取決于比較的準(zhǔn)則,以及一個(gè)實(shí)例是否大于其他的這也取決于其他的準(zhǔn)則)。如果self < other,那__cmp__應(yīng)當(dāng)返回一個(gè)負(fù)整數(shù);如果self == other,則返回0;如果self > other,則返回正整數(shù)。它通常是最好的定義,而不需要你一次就全定義好它們,但當(dāng)你需要用類似的準(zhǔn)則進(jìn)行所有的比較時(shí),__cmp__會(huì)是一個(gè)很好的方式,幫你節(jié)省重復(fù)性和提高明確度。

__eq__(self,other)

定義了相等操作符,==的行為。

__ne__(self,other)

定義了不相等操作符,!=的行為。

__lt__(self,other)

定義了小于操作符,<的行為。

__gt__(self,other)

定義了大于操作符,>的行為。

__le__(self,other)

定義了小于等于操作符,<=的行為。

__ge__(self,other)

定義了大于等于操作符,>=的行為。

舉一個(gè)例子,設(shè)想對(duì)單詞進(jìn)行類定義。我們可能希望按照內(nèi)部對(duì)字符串的默認(rèn)比較行為,即字典序(通過(guò)字母)來(lái)比較單詞,也希望能夠基于某些其他的準(zhǔn)則,像是長(zhǎng)度或音節(jié)數(shù)。在本例中,我們通過(guò)單詞長(zhǎng)度排序,以下給出實(shí)現(xiàn):

classWord(str):'''單詞類,比較定義是基于單詞長(zhǎng)度的'''def__new__(cls,word):#注意,我們使用了__new__,這是因?yàn)閟tr是一個(gè)不可變類型,#所以我們必須更早地初始化它(在創(chuàng)建時(shí))if''inword:print"單詞內(nèi)含有空格,截?cái)嗟降谝徊糠?word=word[:word.index('')]#在出現(xiàn)第一個(gè)空格之前全是字符了現(xiàn)在returnstr.__new__(cls,word)def__gt__(self,other):returnlen(self)>len(other)def__lt__(self,other):returnlen(self)=len(other)def__le__(self,other):returnlen(self)<=?len(other)

神奇方法數(shù)字:

就像你可以通過(guò)重載比較操作符的途徑來(lái)創(chuàng)建你自己的類實(shí)例,你同樣可以重載數(shù)字操作符。

一元操作符:

一元運(yùn)算和函數(shù)僅有一個(gè)操作數(shù),比如負(fù)數(shù),絕對(duì)值等。

__pos__(self)

實(shí)現(xiàn)一元正數(shù)的行為(如:+some_object)

__neg__(self)

實(shí)現(xiàn)負(fù)數(shù)的行為(如: -some_object)

__abs__(self)

實(shí)現(xiàn)內(nèi)建abs()函數(shù)的行為

__invert__(self)

實(shí)現(xiàn)用~操作符進(jìn)行的取反行為。

常規(guī)算數(shù)操作符:

現(xiàn)在我們涵蓋了基本的二元運(yùn)算符:+,-,*等等。其中大部分都是不言自明的。

__add__(self,other)

實(shí)現(xiàn)加法

__sub__(self,other)

實(shí)現(xiàn)減法

__mul__(self,other)

實(shí)現(xiàn)乘法

__floordiv__(self,other)

實(shí)現(xiàn)地板除法,使用//操作符

__div__(self,other)

實(shí)現(xiàn)傳統(tǒng)除法,使用/操作符

__truediv__(self,other)

實(shí)現(xiàn)真正除法。注意,只有當(dāng)你from __future__ import division時(shí)才會(huì)有效

__mod__(self,other)

實(shí)現(xiàn)求模,使用%操作符

__divmod__(self,other)

實(shí)現(xiàn)內(nèi)建函數(shù)divmod()的行為

__pow__(self,other)

實(shí)現(xiàn)乘方,使用**操作符

__lshift__(self,other)

實(shí)現(xiàn)左按位位移,使用<<操作符

__rshift__(self,other)

實(shí)現(xiàn)右按位位移,使用>>操作符

__and__(self,other)

實(shí)現(xiàn)按位與,使用&操作符

__or__(self,other)

實(shí)現(xiàn)按位或,使用|操作符

__xor__(self,other)

實(shí)現(xiàn)按位異或,使用^操作符

反射算數(shù)操作符:

首先舉個(gè)例子:some_object + other。這是“常規(guī)的”加法。而反射其實(shí)相當(dāng)于一回事,除了操作數(shù)改變了改變下位置:other + some_object。在大多數(shù)情況下,反射算術(shù)操作的結(jié)果等價(jià)于常規(guī)算術(shù)操作,所以你盡可以在剛重載完__radd__就調(diào)用__add__。干脆痛快:

__radd__(self,other)

實(shí)現(xiàn)反射加法

__rsub__(self,other)

實(shí)現(xiàn)反射減法

__rmul__(self,other)

實(shí)現(xiàn)反射乘法

__rfloordiv__(self,other)

實(shí)現(xiàn)反射地板除,用//操作符

__rdiv__(self,other)

實(shí)現(xiàn)傳統(tǒng)除法,用/操作符

__rturediv__(self,other)

實(shí)現(xiàn)真實(shí)除法,注意,只有當(dāng)你from __future__ import division時(shí)才會(huì)有效

__rmod__(self,other)

實(shí)現(xiàn)反射求模,用%操作符

__rdivmod__(self,other)

實(shí)現(xiàn)內(nèi)置函數(shù)divmod()的長(zhǎng)除行為,當(dāng)調(diào)用divmod(other,self)時(shí)被調(diào)用

__rpow__(self,other)

實(shí)現(xiàn)反射乘方,用**操作符

__rlshift__(self,other)

實(shí)現(xiàn)反射的左按位位移,使用<<操作符

__rrshift__(self,other)

實(shí)現(xiàn)反射的右按位位移,使用>>操作符

__rand__(self,other)

實(shí)現(xiàn)反射的按位與,使用&操作符

__ror__(self,other)

實(shí)現(xiàn)反射的按位或,使用|操作符

__rxor__(self,other)

實(shí)現(xiàn)反射的按位異或,使用^操作符

增量賦值:

Python也有各種各樣的神奇方法允許用戶自定義增量賦值行為。

這些方法都不會(huì)有返回值,因?yàn)橘x值在Python中不會(huì)有任何返回值。反而它們只是改變類的狀態(tài)。列表如下:

__rxor__(self,other)

實(shí)現(xiàn)加法和賦值

__isub__(self,other)

實(shí)現(xiàn)減法和賦值

__imul__(self,other)

實(shí)現(xiàn)乘法和賦值

__ifloordiv__(self,other)

實(shí)現(xiàn)地板除和賦值,用//=操作符

__idiv__(self,other)

實(shí)現(xiàn)傳統(tǒng)除法和賦值,用/=操作符

__iturediv__(self,other)

實(shí)現(xiàn)真實(shí)除法和賦值,注意,只有當(dāng)你from __future__ import division時(shí)才會(huì)有效

__imod__(self,other)

實(shí)現(xiàn)求模和賦值,用%=操作符

__ipow__(self,other)

實(shí)現(xiàn)乘方和賦值,用**=操作符

__ilshift__(self,other)

實(shí)現(xiàn)左按位位移和賦值,使用<<=操作符

__irshift__(self,other)

實(shí)現(xiàn)右按位位移和賦值,使用>>=操作符

__iand__(self,other)

實(shí)現(xiàn)按位與和賦值,使用&=操作符

__ior__(self,other)

實(shí)現(xiàn)按位或和賦值,使用|=操作符

__ixor__(self,other)

實(shí)現(xiàn)按位異或和賦值,使用^=操作符

類型轉(zhuǎn)換的神奇方法:

Python也有一組神奇方法被設(shè)計(jì)用來(lái)實(shí)現(xiàn)內(nèi)置類型轉(zhuǎn)換函數(shù)的行為,如float()。

__int__(self)

實(shí)現(xiàn)到int的類型轉(zhuǎn)換

__long__(self)

實(shí)現(xiàn)到long的類型轉(zhuǎn)換

__float__(self)

實(shí)現(xiàn)到float的類型轉(zhuǎn)換

__complex__(self)

實(shí)現(xiàn)到復(fù)數(shù)的類型轉(zhuǎn)換

__oct__(self)

實(shí)現(xiàn)到8進(jìn)制的類型轉(zhuǎn)換

__hex__(self)

實(shí)現(xiàn)到16進(jìn)制的類型轉(zhuǎn)換

__index__(self)

實(shí)現(xiàn)一個(gè)當(dāng)對(duì)象被切片到int的類型轉(zhuǎn)換。如果你自定義了一個(gè)數(shù)值類型,考慮到它可能被切片,所以你應(yīng)該重載__index__。

__trunc__(self)

當(dāng)math.trunc(self)被調(diào)用時(shí)調(diào)用。__trunc__應(yīng)當(dāng)返回一個(gè)整型的截?cái)啵?通常是long)。

__coerce__(self,other)

該方法用來(lái)實(shí)現(xiàn)混合模式的算術(shù)。如果類型轉(zhuǎn)換不可能那__coerce__應(yīng)當(dāng)返回None。否則,它應(yīng)當(dāng)返回一對(duì)包含self和other(2元組),且調(diào)整到具有相同的類型。

描述自定義類

用一個(gè)字符串來(lái)說(shuō)明一個(gè)類這通常是有用的。在Python中提供了一些方法讓你可以在你自己的類中自定義內(nèi)建函數(shù)返回你的類行為的描述。

__str__(self)

當(dāng)你定義的類中一個(gè)實(shí)例調(diào)用了str(),用于給它定義行為

__repr__(self)

當(dāng)你定義的類中一個(gè)實(shí)例調(diào)用了repr(),用于給它定義行為。str()和repr()主要的區(qū)別在于它的閱讀對(duì)象。repr()產(chǎn)生的輸出主要為計(jì)算機(jī)可讀(在很多情況下,這甚至可能是一些有效的Python代碼),而str()則是為了讓人類可讀。

__unicode__(self)

當(dāng)你定義的類中一個(gè)實(shí)例調(diào)用了unicode(),用于給它定義行為。unicode()像是str(),只不過(guò)它返回一個(gè)unicode字符串。警惕!如果用戶用你的類中的一個(gè)實(shí)例調(diào)用了str(),而你僅定義了__unicode__(),那它是不會(huì)工作的。以防萬(wàn)一,你應(yīng)當(dāng)總是定義好__str__(),哪怕用戶不會(huì)使用unicode。

__hash__(self)

當(dāng)你定義的類中一個(gè)實(shí)例調(diào)用了hash(),用于給它定義行為。它必須返回一個(gè)整型,而且它的結(jié)果是用于來(lái)在字典中作為快速鍵比對(duì)。

__nonzero__(self)

當(dāng)你定義的類中一個(gè)實(shí)例調(diào)用了bool(),用于給它定義行為。返回True或False,取決于你是否考慮一個(gè)實(shí)例是True或False的。

我們已經(jīng)相當(dāng)漂亮地干完了神奇方法無(wú)聊的部分(無(wú)示例),至此我們已經(jīng)討論了一些基礎(chǔ)的神奇方法,是時(shí)候讓我們向高級(jí)話題移動(dòng)了。

控制屬性訪問(wèn)

Python通過(guò)神奇的方法實(shí)現(xiàn)了大量的封裝,而不是通過(guò)明確的方法或字段修飾符。例如:

__getattr__(self,name)

你可以為用戶在試圖訪問(wèn)不存在(不論是存在或尚未建立)的類屬性時(shí)定義其行為。這對(duì)捕捉和重定向常見(jiàn)的拼寫(xiě)錯(cuò)誤,給出使用屬性警告是有用的(只要你愿意,你仍舊可選計(jì)算,返回那個(gè)屬性)或拋出一個(gè)AttributeError異常。這個(gè)方法只適用于訪問(wèn)一個(gè)不存在的屬性,所以,這不算一個(gè)真正封裝的解決之道。

__setattr__(self,name,value)

不像__getattr__,__setattr__是一個(gè)封裝的解決方案。它允許你為一個(gè)屬性賦值時(shí)候的行為,不論這個(gè)屬性是否存在。這意味著你可以給屬性值的任意變化自定義規(guī)則。然而,你需要在意的是你要小心使用__setattr__,在稍后的列表中會(huì)作為例子給出。

__delattr__

這等價(jià)于__setattr__,但是作為刪除類屬性而不是set它們。它需要相同的預(yù)防措施,就像__setattr__,防止無(wú)限遞歸(當(dāng)在__delattr__中調(diào)用del self.name會(huì)引起無(wú)限遞歸)。

__getattribute__(self,name)

__getattribute__良好地適合它的同伴們__setattr__和__delattr__。可我卻不建議你使用它。

__getattribute__只能在新式類中使用(在Python的最新版本中,所有的類都是新式類,在稍舊的版本中你可以通過(guò)繼承object類來(lái)創(chuàng)建一個(gè)新式類。它允許你定規(guī)則,在任何時(shí)候不管一個(gè)類屬性的值那時(shí)候是否可訪問(wèn)的。)它會(huì)因?yàn)樗耐橹械某鲥e(cuò)連坐受到某些無(wú)限遞歸問(wèn)題的困擾(這時(shí)你可以通過(guò)調(diào)用基類的__getattribute__方法來(lái)防止發(fā)生)。當(dāng)__getattribute__被實(shí)現(xiàn)而又只調(diào)用了該方法如果__getattribute__被顯式調(diào)用或拋出一個(gè)AttributeError異常,同時(shí)也主要避免了對(duì)__getattr__的依賴。這個(gè)方法可以使用,不過(guò)我不推薦它是因?yàn)樗幸粋€(gè)小小的用例(雖說(shuō)比較少見(jiàn),但我們需要特殊行為以獲取一個(gè)值而不是賦值)以及它真的很難做到實(shí)現(xiàn)0bug。

你可以很容易地在你自定義任何類屬性訪問(wèn)方法時(shí)引發(fā)一個(gè)問(wèn)題。參考這個(gè)例子:

def__setattr__(self,name,value):self.name=value#當(dāng)每次給一個(gè)類屬性賦值時(shí),會(huì)調(diào)用__setattr__(),這就形成了遞歸#因?yàn)樗嬲暮x是self.__setattr__('name',value)#所以這方法不停地調(diào)用它自己,變成了一個(gè)無(wú)法退出的遞歸最終引發(fā)crashdef__setattr__(self,name,value):self.__dict__[name]=value#給字典中的name賦值#在此自定義行為

以下是一個(gè)關(guān)于特殊屬性訪問(wèn)方法的實(shí)際例子(注意,我們使用super因?yàn)椴⒎撬蓄惗加衉_dict__類屬性):

classAccessCounter:'''一個(gè)類包含一個(gè)值和實(shí)現(xiàn)了一個(gè)訪問(wèn)計(jì)數(shù)器。當(dāng)值每次發(fā)生變化時(shí),計(jì)數(shù)器+1'''def__init__(self,val):super(AccessCounter,self).__setattr__('counter',0)super(AccessCounter,self).__setattr__('value',val)def__setattr__(self,name,value):ifname=='value':super(AccessCounter,self).__setattr__('counter',self.counter+1)#Makethisunconditional.#如果你想阻止其他屬性被創(chuàng)建,拋出AttributeError(name)異常super(AccessCounter,self).__setattr__(name,value)def__delattr__(self,name)ifname=='value':super(AccessCounter,self).__setattr__('counter',self.counter+1)super(AccessCounter,self).__delattr__(name)

制作自定義序列

很有多種方式可以讓你的類表現(xiàn)得像內(nèi)建序列(字典,元組,列表,字符串等)。這些是我迄今為止最喜歡的神奇方法了,因?yàn)椴缓侠淼目刂扑鼈冑x予了你一種魔術(shù)般地讓你的類實(shí)例整個(gè)全局函數(shù)數(shù)組漂亮工作的方式。

__len__(self)

返回容器的長(zhǎng)度。部分protocol同時(shí)支持可變和不可變?nèi)萜?/p>

__getitem__(self,key)

定義當(dāng)某一個(gè)item被訪問(wèn)時(shí)的行為,使用self[key]表示法。這個(gè)同樣也是部分可變和不可變?nèi)萜鱬rotocol。這也可拋出適當(dāng)?shù)漠惓?TypeError 當(dāng)key的類型錯(cuò)誤,或沒(méi)有值對(duì)應(yīng)Key時(shí)。

__setitem__(self,key,value)

定義當(dāng)某一個(gè)item被賦值時(shí)候的行為,使用self[key]=value表示法。這也是部分可變和不可變?nèi)萜鱬rotocol。再一次重申,你應(yīng)當(dāng)在適當(dāng)之處拋出KeyError和TypeError異常。

__delitem__(self,key)

定義當(dāng)某一個(gè)item被刪除(例如 del self[key])時(shí)的行為。這僅是部分可變?nèi)萜鞯膒rotocol。在一個(gè)無(wú)效key被使用后,你必須拋出一個(gè)合適的異常。

__iter__(self)

應(yīng)該給容器返回一個(gè)迭代器。迭代器會(huì)返回若干內(nèi)容,大多使用內(nèi)建函數(shù)iter()表示。當(dāng)一個(gè)容器使用形如for x in container:的循環(huán)。迭代器本身就是其對(duì)象,同時(shí)也要定義好一個(gè)__iter__方法來(lái)返回自身。

__reversed__(self)

當(dāng)定義調(diào)用內(nèi)建函數(shù)reversed()時(shí)的行為。應(yīng)該返回一個(gè)反向版本的列表。

__contains__(self,item)

__contains__為成員關(guān)系,用in和not in測(cè)試時(shí)定義行為。那你會(huì)問(wèn)這個(gè)為何不是一個(gè)序列的protocol的一部分?這是因?yàn)楫?dāng)__contains__未定義,Python就會(huì)遍歷序列,如果遇到正在尋找的item就會(huì)返回True。

__concat__(self,other)

最后,你可通過(guò)__concat__定義你的序列和另外一個(gè)序列的連接。應(yīng)該從self和other返回一個(gè)新構(gòu)建的序列。當(dāng)調(diào)用2個(gè)序列時(shí)__concat__涉及操作符+

在我們的例子中,讓我們看一下一個(gè)list實(shí)現(xiàn)的某些基礎(chǔ)功能性的構(gòu)建。可能會(huì)讓你想起你使用的其他語(yǔ)言(比如Haskell)。

classFunctionalList:'''類覆蓋了一個(gè)list的某些額外的功能性魔法,像head,tail,init,last,drop,andtake'''def__init__(self,values=None):ifvaluesisNone:self.values=[]else:self.values=valuesdef__len__(self):returnlen(self.values)def__getitem__(self,key):#如果key是非法的類型和值,那么listvaluse會(huì)拋出異常returnself.values[key]def__setitem__(self,key,value):self.values[key]=valuedef__delitem__(self,key):delself.values[key]def__iter__(self):returniter(self.values)def__reversed__(self):returnreversed(self.values)defappend(self,value):self.values.append(value)defhead(self):#獲得第一個(gè)元素returnself.values[0]deftail(self):#獲得在第一個(gè)元素后的其他所有元素returnself.values[1:]definit(self):#獲得除最后一個(gè)元素的序列returnself.values[:-1]deflast(last):#獲得最后一個(gè)元素returnself.values[-1]defdrop(self,n):#獲得除前n個(gè)元素的序列returnself.values[n:]deftake(self,n):#獲得前n個(gè)元素returnself.values[:n]

反射

你也可以通過(guò)定義神奇方法來(lái)控制如何反射使用內(nèi)建函數(shù)isinstance()和issubclass()的行為。這些神奇方法是:

__instancecheck__(self,instance)

檢查一個(gè)實(shí)例是否是你定義類中的一個(gè)實(shí)例(比如,isinstance(instance, class))

__subclasscheck__(self,subclass)

檢查一個(gè)類是否是你定義類的子類(比如,issubclass(subclass, class))

可調(diào)用對(duì)象

這是Python中一個(gè)特別的神奇方法,它允許你的類實(shí)例像函數(shù)。所以你可以“調(diào)用”它們,把他們當(dāng)做參數(shù)傳遞給函數(shù)等等。這是另一個(gè)強(qiáng)大又便利的特性讓Python的編程變得更可愛(ài)了。

__call__(self,[args…])

允許類實(shí)例像函數(shù)一樣被調(diào)用。本質(zhì)上,這意味著x()等價(jià)于x.__call__()。注意,__call__需要的參數(shù)數(shù)目是可變的,也就是說(shuō)可以對(duì)任何函數(shù)按你的喜好定義參數(shù)的數(shù)目定義__call__。

__call__可能對(duì)于那些經(jīng)常改變狀態(tài)的實(shí)例來(lái)說(shuō)是極其有用的。“調(diào)用”實(shí)例是一種順應(yīng)直覺(jué)且優(yōu)雅的方式來(lái)改變對(duì)象的狀態(tài)。下面一個(gè)例子是一個(gè)類表示一個(gè)實(shí)體在一個(gè)平面上的位置:

classEntity:'''描述實(shí)體的類,被調(diào)用的時(shí)候更新實(shí)體的位置'''def__init__(self,size,x,y):self.x,self.y=x,yself.size=sizedef__call__(self,x,y):'''改變實(shí)體的位置'''self.x,self.y=x,y#省略...

上下文管理器

上下文管理允許對(duì)對(duì)象進(jìn)行設(shè)置和清理動(dòng)作,用with聲明進(jìn)行已經(jīng)封裝的操作。上下文操作的行為取決于2個(gè)神奇方法:

__enter__(self)

定義塊用with聲明創(chuàng)建出來(lái)時(shí)上下文管理應(yīng)該在塊開(kāi)始做什么。

__exit__(self,exception_type,exception_value,traceback)

定義在塊執(zhí)行(或終止)之后上下文管理應(yīng)該做什么。

你也可以使用這些方法去創(chuàng)建封裝其他對(duì)象通用的上下文管理。看下面的例子:

classCloser:'''用with聲明一個(gè)上下文管理用一個(gè)close方法自動(dòng)關(guān)閉一個(gè)對(duì)象'''def__init__(self,obj):self.obj=objdef__enter__(self):returnself.obj#綁定目標(biāo)def__exit__(self,exception_type,exception_val,trace):try:self.obj.close()exceptAttributeError:#obj不具備closeprint'Notclosable.'returnTrue#成功處理異常

以下是一個(gè)對(duì)于Closer實(shí)際應(yīng)用的一個(gè)例子,使用一個(gè)FTP連接進(jìn)行的演示(一個(gè)可關(guān)閉的套接字):

>>>frommagicmethodsimportCloser>>>fromftplibimport:;;>>>withCloser(FTP('ftp.somsite.com'))asconn:...conn.dir()...#省略的輸出>>>conn.dir()#一個(gè)很長(zhǎng)的AttributeError消息,不能關(guān)閉使用的一個(gè)連接>>>withCloser(int(5))asi:...i+=1...Notcloseable.>>>i6

構(gòu)建描述符對(duì)象

描述符可以改變其他對(duì)象,也可以是訪問(wèn)類中任一的getting,setting,deleting。

作為一個(gè)描述符,一個(gè)類必須至少實(shí)現(xiàn)__get__,__set__,和__delete__中的一個(gè)。讓我們快點(diǎn)看一下這些神奇方法吧:

__get__(self,instance,owner)

當(dāng)描述符的值被取回時(shí)定義其行為。instance是owner對(duì)象的一個(gè)實(shí)例,owner是所有類。

__set__(self,instance,value)

當(dāng)描述符的值被改變時(shí)定義其行為。instance是owner對(duì)象的一個(gè)實(shí)例,value是設(shè)置的描述符的值

__delete__(self,instance)

當(dāng)描述符的值被刪除時(shí)定義其行為。instance是owner對(duì)象的一個(gè)實(shí)例。

現(xiàn)在,有一個(gè)有用的描述符應(yīng)用例子:?jiǎn)挝晦D(zhuǎn)換策略

classMeter(object):'''米描述符'''def__init__(self,value=0.0):self.value=float(value)def__get__(self,instance,owner):returnself.valuedef__set__(self,instance,value):self.value=float(value)classFoot(object):'''英尺描述符'''def__get__(self,instance,owner):returninstance.meter*3.2808def__set__(self,instance,value):instance.meter=float(value)/3.2808classDistance(object):'''表示距離的類,控制2個(gè)描述符:feet和meters'''meter=Meter()foot=Foot()

總結(jié)

這份指南的目標(biāo)就是讓任何人都能讀懂它,不管讀者們是否具備Python或面向?qū)ο蟮木幊探?jīng)驗(yàn)。如果你正準(zhǔn)備學(xué)習(xí)Python,那你已經(jīng)獲得了編寫(xiě)功能豐富、優(yōu)雅、易用的類的寶貴知識(shí)。如果你是一名中級(jí)Python程序員,你有可能已經(jīng)拾起了一些概念、策略和一些好的方法來(lái)減少你編寫(xiě)的代碼量。如果你是一名Python專家,你可能已經(jīng)回顧了某些你可能已經(jīng)遺忘的知識(shí)點(diǎn),或者你又又有一些新的發(fā)現(xiàn)。不管你的經(jīng)驗(yàn)等級(jí)如何,希望你在這次Python神奇方法之旅中有所收獲!

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 初始化
    +關(guān)注

    關(guān)注

    0

    文章

    49

    瀏覽量

    11837
  • python
    +關(guān)注

    關(guān)注

    56

    文章

    4782

    瀏覽量

    84464

原文標(biāo)題:【Python大神秘籍Top10】這些竅門(mén)99%的人都不知道

文章出處:【微信號(hào):AI_era,微信公眾號(hào):新智元】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    一鍵重裝系統(tǒng),魔法系統(tǒng)重裝大師v1.0

    法系統(tǒng)重裝大師軟件具有自動(dòng)識(shí)別電腦硬件并智能云匹配最佳系統(tǒng)版本。不管安裝XP、Win7還是Win8系統(tǒng),都能實(shí)現(xiàn)一鍵在線重裝,輕松解決電腦系統(tǒng)重裝問(wèn)題。并提供一鍵備份還原工具,幫助用
    發(fā)表于 02-01 14:36

    一鍵重裝系統(tǒng),魔法系統(tǒng)重裝大師v1.6

    法系統(tǒng)重裝大師軟件具有自動(dòng)識(shí)別電腦硬件并智能云匹配最佳系統(tǒng)版本。不管安裝XP、Win7還是Win8系統(tǒng),都能實(shí)現(xiàn)一鍵在線重裝,輕松解決電腦系統(tǒng)重裝問(wèn)題。并提供一鍵備份還原工具,幫助用
    發(fā)表于 02-26 17:53

    四大Python執(zhí)行系統(tǒng)命令方法

    Python是一款操作簡(jiǎn)單的編程語(yǔ)言,內(nèi)置豐富的庫(kù),能夠很容易的實(shí)現(xiàn)強(qiáng)大的功能,在使用Python進(jìn)行框架搭建時(shí),往往需要用到Python執(zhí)行系統(tǒng)命令,一些開(kāi)發(fā)人員對(duì)此不熟悉,以下是具
    發(fā)表于 04-09 17:44

    基于Python的礦山遙感監(jiān)測(cè)系統(tǒng)開(kāi)發(fā)的方法

    目前,很多學(xué)者都是從宏觀上討論遙感和GIS一體化集成的可能性及集成的方法,但這些研究在GIS和RS方向只是對(duì)Python集成研究的思路或某一功能的介紹,并沒(méi)有一個(gè)基于Python開(kāi)發(fā)的集成GIS
    發(fā)表于 08-11 06:21

    Python中的類方法、實(shí)例方法和靜態(tài)方法

    Python中實(shí)例屬性和實(shí)例方法Python中類屬性和類方法Python中調(diào)用類方法
    發(fā)表于 11-05 06:25

    構(gòu)建Python開(kāi)發(fā)環(huán)境的方法

    本系列教程將向大家講述,在自己的計(jì)算機(jī)上構(gòu)建完善的嵌入式系統(tǒng)開(kāi)發(fā)環(huán)境的方法。本文將向大家講述構(gòu)建Python開(kāi)發(fā)環(huán)境的方法Python簡(jiǎn)介
    發(fā)表于 11-08 08:01

    嵌入式系統(tǒng)概述知識(shí)梳理

    《嵌入式系統(tǒng)》 |(一)嵌入式系統(tǒng)概述 知識(shí)梳理《嵌入式系統(tǒng)》 |(二)ARM Cortex M3 體系結(jié)構(gòu) 知識(shí)梳理嵌入式
    發(fā)表于 12-22 06:53

    衛(wèi)星電視地球接收站測(cè)量方法系統(tǒng)測(cè)量 GB/T 11298.1

    衛(wèi)星電視地球接收站測(cè)量方法系統(tǒng)測(cè)量 GB/T 11298.1-1997 范圍本標(biāo)準(zhǔn)規(guī)定了衛(wèi)星電視地球接收站的系統(tǒng)測(cè)量方法本標(biāo)準(zhǔn)適用于模擬衛(wèi)星電視地球接收站的系統(tǒng)測(cè)量引用
    發(fā)表于 10-05 10:30 ?332次下載

    法系統(tǒng)數(shù)字審訊系統(tǒng)的設(shè)計(jì)與應(yīng)用

    法系統(tǒng)數(shù)字審訊系統(tǒng)的設(shè)計(jì)與應(yīng)用
    發(fā)表于 12-27 22:17 ?0次下載

    相關(guān)函數(shù)脈沖響應(yīng)法系統(tǒng)實(shí)時(shí)辨識(shí)_鄧春龍

    相關(guān)函數(shù)脈沖響應(yīng)法系統(tǒng)實(shí)時(shí)辨識(shí)_鄧春龍
    發(fā)表于 03-15 09:36 ?1次下載

    Python中輕松調(diào)用Java方法-PyJNIus

    PyJNIus 是一個(gè)神奇Python 第三方模塊。它能使用Java本地接口將Java類作為Python類訪問(wèn)的Python模塊。
    的頭像 發(fā)表于 02-24 13:49 ?1693次閱讀

    梳理單片機(jī)學(xué)習(xí)方法、產(chǎn)品開(kāi)發(fā)流程

    梳理單片機(jī)學(xué)習(xí)方法、產(chǎn)品開(kāi)發(fā)流程
    的頭像 發(fā)表于 09-21 17:20 ?621次閱讀
    <b class='flag-5'>梳理</b>單片機(jī)學(xué)習(xí)<b class='flag-5'>方法</b>、產(chǎn)品開(kāi)發(fā)流程

    PyJNIus:在Python中輕松調(diào)用Java方法

    PyJNIus 是一個(gè)神奇Python 第三方模塊。它能使用Java本地接口將Java類作為Python類訪問(wèn)的Python模塊。 如果你需要在
    的頭像 發(fā)表于 10-30 11:32 ?866次閱讀

    PyJNIus :讓你在Python中輕松調(diào)用Java方法

    PyJNIus 是一個(gè)神奇Python 第三方模塊。它能使用Java本地接口將Java類作為Python類訪問(wèn)的Python模塊。 如果你需要在
    的頭像 發(fā)表于 11-01 10:45 ?800次閱讀

    查看python安裝路徑的方法

    如何查看Python安裝路徑,以及各個(gè)操作系統(tǒng)下的細(xì)節(jié)和注意事項(xiàng)。 一、Windows操作系統(tǒng)下查看Python安裝路徑的方法 對(duì)于Wind
    的頭像 發(fā)表于 11-29 14:54 ?1.1w次閱讀