摘要:在任何新式類的方法,不能調(diào)用自身的來(lái)制造實(shí)例,因?yàn)檫@會(huì)造成死循環(huán)。因此必須避免類似以下的寫法在中避免或。注意如果沒(méi)有返回即當(dāng)前類的實(shí)例,那么當(dāng)前類的方法是不會(huì)被調(diào)用的。是最基本的用于比較的魔術(shù)方法。
1、__ new__, __ init__, __ call__
__ new__(cls, *args, **kwargs) 創(chuàng)建對(duì)象時(shí)調(diào)用,返回當(dāng)前對(duì)象的一個(gè)實(shí)例;注意:這里的第一個(gè)參數(shù)是cls即class本身
__ init__(self, *args, **kwargs) 創(chuàng)建完對(duì)象后調(diào)用,對(duì)當(dāng)前對(duì)象的實(shí)例的一些初始化,無(wú)返回值,即在調(diào)用__new__之后,根據(jù)返回的實(shí)例初始化;注意,這里的第一個(gè)參數(shù)是self即對(duì)象本身
__ call__(self, *args, **kwargs) 如果類實(shí)現(xiàn)了這個(gè)方法,相當(dāng)于把這個(gè)類型的對(duì)象當(dāng)作函數(shù)來(lái)使用,相當(dāng)于 重載了括號(hào)運(yùn)算符
繼承自object的新式類才有__ new__
__ new__至少要有一個(gè)參數(shù)cls,代表要實(shí)例化的類,此參數(shù)在實(shí)例化時(shí)由Python解釋器自動(dòng)提供
__ new__必須要有返回值,返回實(shí)例化出來(lái)的實(shí)例,這點(diǎn)在自己實(shí)現(xiàn)_ new__時(shí)要特別注意,可以return父類__ new__出來(lái)的實(shí)例,或者直接是object的 _new__出來(lái)的實(shí)例
__ init__有一個(gè)參數(shù)self,就是這個(gè) __ new__返回的實(shí)例,__ init__在__ new__的基礎(chǔ)上可以完成一些其它初始化的動(dòng)作,__ init__不需要返回值
若_ _new__沒(méi)有正確返回當(dāng)前類cls的實(shí)例,那__ init__是不會(huì)被調(diào)用的,即使是父類的實(shí)例也不行
http://www.cnblogs.com/ifantastic/p/3175735.html
class Foo(object): def __init__(self, *args, **kwargs): ... def __new__(cls, *args, **kwargs): return object.__new__(cls, *args, **kwargs) # 以上return等同于 # return object.__new__(Foo, *args, **kwargs) # return Stranger.__new__(cls, *args, **kwargs) # return Child.__new__(cls, *args, **kwargs) class Child(Foo): def __new__(cls, *args, **kwargs): return object.__new__(cls, *args, **kwargs) # 如果Child中沒(méi)有定義__new__()方法,那么會(huì)自動(dòng)調(diào)用其父類的__new__()方法來(lái)制造實(shí)例,即 Foo.__new__(cls, *args, **kwargs)。 # 在任何新式類的__new__()方法,不能調(diào)用自身的__new__()來(lái)制造實(shí)例,因?yàn)檫@會(huì)造成死循環(huán)。因此必須避免類似以下的寫法: # 在Foo中避免:return Foo.__new__(cls, *args, **kwargs)或return cls.__new__(cls, *args, **kwargs)。Child同理。 # 使用object或者沒(méi)有血緣關(guān)系的新式類的__new__()是安全的,但是如果是在有繼承關(guān)系的兩個(gè)類之間,應(yīng)避免互調(diào)造成死循環(huán),例如:(Foo)return Child.__new__(cls), (Child)return Foo.__new__(cls)。 class Stranger(object): ... # 在制造Stranger實(shí)例時(shí),會(huì)自動(dòng)調(diào)用 object.__new__(cls)
也可以這么調(diào)用 new_class = super(RenameMethodsBase, cls).__new__(cls, name, bases, attrs)
通常來(lái)說(shuō),新式類開始實(shí)例化時(shí),new()方法會(huì)返回cls(cls指代當(dāng)前類)的實(shí)例,然后該類的init()方法作為構(gòu)造方法會(huì)接收這個(gè)實(shí)例(即self)作為自己的第一個(gè)參數(shù),然后依次傳入new()方法中接收的位置參數(shù)和命名參數(shù)。
注意:如果new()沒(méi)有返回cls(即當(dāng)前類)的實(shí)例,那么當(dāng)前類的init()方法是不會(huì)被調(diào)用的。如果new()返回其他類(新式類或經(jīng)典類均可)的實(shí)例,那么只會(huì)調(diào)用被返回的那個(gè)類的構(gòu)造方法。
class Foo(object): def __init__(self, *args, **kwargs): ... def __new__(cls, *args, **kwargs): return object.__new__(Stranger, *args, **kwargs) class Stranger(object): ... foo = Foo() print type(foo) # 打印的結(jié)果顯示foo其實(shí)是Stranger類的實(shí)例。 # 因此可以這么描述__new__()和__ini__()的區(qū)別,在新式類中__new__()才是真正的實(shí)例化方法,為類提供外殼制造出實(shí)例框架,然后調(diào)用該框架內(nèi)的構(gòu)造方法__init__()使其豐滿。 # 如果以建房子做比喻,__new__()方法負(fù)責(zé)開發(fā)地皮,打下地基,并將原料存放在工地。而__init__()方法負(fù)責(zé)從工地取材料建造出地皮開發(fā)招標(biāo)書中規(guī)定的大樓,__init__()負(fù)責(zé)大樓的細(xì)節(jié)設(shè)計(jì),建造,裝修使其可交付給客戶。
2、__ del__
它不實(shí)現(xiàn)語(yǔ)句 del x (以上代碼將不會(huì)翻譯為 x.__ del__() )。它定義的是當(dāng)一個(gè)對(duì)象進(jìn)行垃圾回收時(shí)候的行為。當(dāng)一個(gè)對(duì)象在刪除的時(shí)需要更多的清潔工作的時(shí)候此方法會(huì)很有用,比如套接字對(duì)象或者是文件對(duì)象。注意,如果解釋器退出的時(shí)候?qū)ο筮€存存在,就不能保證 __ del__ 能夠被執(zhí)行
from os.path import join class FileObject: """給文件對(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() del self.file
3、用于比較的魔術(shù)方法
Python對(duì)實(shí)現(xiàn)對(duì)象的比較,使用魔術(shù)方法進(jìn)行了大的逆轉(zhuǎn),使他們非常直觀而不是笨拙的方法調(diào)用。 而且還提供了一種方法可以重寫Python對(duì)對(duì)象比較的默認(rèn)行為(通過(guò)引用)。以下是這些方法和他們的作用。 __cmp__(self, other) __cmp__ 是最基本的用于比較的魔術(shù)方法。它實(shí)際上實(shí)現(xiàn)了所有的比較符號(hào)(<,==,!=,etc.),但是它的表現(xiàn)并不會(huì)總是如你所愿(比如,當(dāng)一個(gè)實(shí)例與另一個(gè)實(shí)例相等是通過(guò)一個(gè)規(guī)則來(lái)判斷,而一個(gè)實(shí)例大于另外一個(gè)實(shí)例是通過(guò)另外一個(gè)規(guī)則來(lái)判斷)。 如果 self < other 的話 __cmp__ 應(yīng)該返回一個(gè)負(fù)數(shù),當(dāng) self == other 的時(shí)候會(huì)返回0 ,而當(dāng) self > other 的時(shí)候會(huì)返回正數(shù)。通常最好的一種方式是去分別定義每一個(gè)比較符號(hào)而不是一次性將他們都定義。 但是 __cmp__ 方法是你想要實(shí)現(xiàn)所有的比較符號(hào)而一個(gè)保持清楚明白的一個(gè)好的方法。 __eq__(self, other) 定義了等號(hào)的行為, == 。 __ne__(self, other) 定義了不等號(hào)的行為, != 。 __lt__(self, other) 定義了小于號(hào)的行為, < 。 __gt__(self, other) 定義了大于等于號(hào)的行為, >= 。 class Word(str): """存儲(chǔ)單詞的類,定義比較單詞的幾種方法""" def __new__(cls, word): # 注意我們必須要用到__new__方法,因?yàn)閟tr是不可變類型 # 所以我們必須在創(chuàng)建的時(shí)候?qū)⑺跏蓟? if " " in word: print "Value contains spaces. Truncating to first space." word = word[:word.index(" ")] #單詞是第一個(gè)空格之前的所有字符 return str.__new__(cls, word) def __gt__(self, other): return len(self) > len(other) def __lt__(self, other): return len(self) < len(other) def __ge__(self, other): return len(self) >= len(other) def __le__(self, other): return len(self) <= len(other)
http://pycoders-weekly-chinese.readthedocs.org/en/latest/issue6/a-guid...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/37574.html
摘要:所以準(zhǔn)確來(lái)說(shuō)是和共同構(gòu)成了構(gòu)造函數(shù)是用來(lái)創(chuàng)建類并返回這個(gè)類的實(shí)例而只是將傳入的參數(shù)來(lái)初始化該實(shí)例在創(chuàng)建一個(gè)實(shí)例的過(guò)程中必定會(huì)被調(diào)用但就不一定,比如通過(guò)的方式反序列化一個(gè)實(shí)例時(shí)就不會(huì)調(diào)用。 前言 在Python中,所有以__雙下劃線包起來(lái)的方法,都統(tǒng)稱為魔術(shù)方法。比如我們接觸最多的__init__. 有些魔術(shù)方法,我們可能以后一輩子都不會(huì)再遇到了,這里也就只是簡(jiǎn)單介紹下; 而有些魔術(shù)方法...
摘要:的魔術(shù)方法是中那些預(yù)定義的像類型的函數(shù)。使用的魔術(shù)方法的最大優(yōu)勢(shì)在于提供了簡(jiǎn)單的方法讓對(duì)象可以表現(xiàn)得像內(nèi)置類型一樣。廖雪峰老師教程里寫的是方法,不知道為啥。 Python的魔術(shù)方法是Python中那些預(yù)定義的像__XXX__類型的函數(shù)。使用Python的魔術(shù)方法的最大優(yōu)勢(shì)在于python提供了簡(jiǎn)單的方法讓對(duì)象可以表現(xiàn)得像內(nèi)置類型一樣。 __str__函數(shù) __str__函數(shù)用于處理打印...
摘要:注原文地址為我的一個(gè)同事提到他錯(cuò)過(guò)了的正則表達(dá)式的語(yǔ)法糖。首先,從正則表達(dá)式檢索捕捉組需要兩個(gè)步驟。語(yǔ)法糖為了好玩,我把一個(gè)小小的增加了一些語(yǔ)法糖的正則表達(dá)式庫(kù)的幫助類放在一起。調(diào)用將調(diào)用類的方法。 注:原文地址為 Playing with Python Magic Methods to make a nicer Regex API 我的一個(gè)同事提到,他錯(cuò)過(guò)了 Ruby 的正...
閱讀 2940·2021-10-14 09:43
閱讀 2885·2021-10-14 09:42
閱讀 4668·2021-09-22 15:56
閱讀 2374·2019-08-30 10:49
閱讀 1596·2019-08-26 13:34
閱讀 2386·2019-08-26 10:35
閱讀 606·2019-08-23 17:57
閱讀 2031·2019-08-23 17:15