python __new__中单例的作用
__new__() 方法的特性:
- __new__() 方法是在類準(zhǔn)備將自身實(shí)例化時(shí)調(diào)用。
- __new__() 方法始終都是類的靜態(tài)方法,即使沒有被加上靜態(tài)方法裝飾器。
- 類的實(shí)例化和它的構(gòu)造方法通常都是這個(gè)樣子:
?
?
正如以上所示,一個(gè)類可以有多個(gè)位置參數(shù)和多個(gè)命名參數(shù),而在實(shí)例化開始之后,在調(diào)用 __init__() 方法之前,Python 首先調(diào)用 __new__() 方法:
def __new__(cls, *args, **kwargs):...
第一個(gè)參數(shù)cls是當(dāng)前正在實(shí)例化的類。
- 如果要得到當(dāng)前類的實(shí)例,應(yīng)當(dāng)在當(dāng)前類中的 __new__() 方法語(yǔ)句中調(diào)用當(dāng)前類的父類的 __new__() 方法。
例如,如果當(dāng)前類是直接繼承自 object,那當(dāng)前類的 __new__() 方法返回的對(duì)象應(yīng)該為:
def __new__(cls, *args, **kwargs):...return object.__new__(cls)
注意:
事實(shí)上如果(新式)類中沒有重寫__new__()方法,即在定義新式類時(shí)沒有重新定義__new__()時(shí),Python默認(rèn)是調(diào)用該類的直接父類的__new__()方法來構(gòu)造該類的實(shí)例,如果該類的父類也沒有重寫__new__(),那么將一直按此規(guī)矩追溯至object的__new__()方法,因?yàn)閛bject是所有新式類的基類。
?
而如果新式類中重寫了__new__()方法,那么你可以自由選擇任意一個(gè)的其他的新式類(必定要是新式類,只有新式類必定都有__new__(),因?yàn)樗行率筋惗际莖bject的后代,而經(jīng)典類則沒有__new__()方法)的__new__()方法來制造實(shí)例,包括這個(gè)新式類的所有前代類和后代類,只要它們不會(huì)造成遞歸死循環(huán)。具體看以下代碼解釋:
?
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中沒有定義__new__()方法,那么會(huì)自動(dòng)調(diào)用其父類的__new__()方法來制造實(shí)例,即 Foo.__new__(cls, *args, **kwargs)。 # 在任何新式類的__new__()方法,不能調(diào)用自身的__new__()來制造實(shí)例,因?yàn)檫@會(huì)造成死循環(huán)。因此必須避免類似以下的寫法: # 在Foo中避免:return Foo.__new__(cls, *args, **kwargs)或return cls.__new__(cls, *args, **kwargs)。Child同理。 # 使用object或者沒有血緣關(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)?
?
- ?通常來說,新式類開始實(shí)例化時(shí),__new__()方法會(huì)返回cls(cls指代當(dāng)前類)的實(shí)例,然后該類的__init__()方法作為構(gòu)造方法會(huì)接收這個(gè)實(shí)例(即self)作為自己的第一個(gè)參數(shù),然后依次傳入__new__()方法中接收的位置參數(shù)和命名參數(shù)。
?
注意:如果__new__()沒有返回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ì),建造,裝修使其可交付給客戶。?
單例的作用就是為了節(jié)約系統(tǒng)資源,每每生成一個(gè)對(duì)象的時(shí)候都回去占用內(nèi)存空間,因此單例就可以結(jié)局這個(gè)問題 #非單例模式,非單例模式在每次實(shí)例化的時(shí)候都會(huì)去調(diào)用內(nèi)存生,這樣調(diào)用的次數(shù)多了,就可能會(huì)造成內(nèi)存的浪費(fèi)class A(object):passa=A() b=A() print(id(a)) print(id(b))輸出結(jié)果 3000151570976 3000151571312#單例模式 #講解:在類開始之前會(huì)調(diào)用類的new方法去生成一個(gè)對(duì)象,所以我們只需要在類調(diào)用錢做處理就好了 class B(object):__instrance = None #定義一個(gè)變量def __new__(cls):if cls.__instrance == None:cls.__instrance = object.__new__(cls) #如果變量是None說明是第一次調(diào)用,就生成一個(gè)對(duì)象,return cls.__instranceelse:return cls.__instrance #如果不是就直接返回上次生成好了的對(duì)象c=B() d=B() print(id(c)) print(id(d))輸出結(jié)果 3000151571592 3000151571592#instrance :實(shí)例總結(jié):
__new__至少要有一個(gè)參數(shù)cls,代表要實(shí)例化的類,此參數(shù)在實(shí)例化時(shí)由Python解釋器自動(dòng)提供
__new__必須要有返回值,返回實(shí)例化出來的實(shí)例,這點(diǎn)在自己實(shí)現(xiàn)__new__時(shí)要特別注意,可以return父類__new__出來的實(shí)例,或者直接是object的__new__出來的實(shí)例
__init__有一個(gè)參數(shù)self,就是這個(gè)__new__返回的實(shí)例,__init__在__new__的基礎(chǔ)上可以完成一些其它初始化的動(dòng)作,__init__不需要返回值
我們可以將類比作制造商,__new__方法就是前期的原材料購(gòu)買環(huán)節(jié),__init__方法就是在有原材料的基礎(chǔ)上,加工,初始化商品環(huán)節(jié)
參考自http://www.cnblogs.com/ifantastic/p/3175735.html
總結(jié)
以上是生活随笔為你收集整理的python __new__中单例的作用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: excel条件格式详解
- 下一篇: idea卸载不干净怎么办_fxfacto