日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python __new__中单例的作用

發布時間:2025/3/15 python 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python __new__中单例的作用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

__new__() 方法的特性:

  • __new__() 方法是在類準備將自身實例化時調用。
  • __new__() 方法始終都是類的靜態方法,即使沒有被加上靜態方法裝飾器。
  • 類的實例化和它的構造方法通常都是這個樣子:
class MyClass(object):def __init__(self, *args, **kwargs):...# 實例化 myclass = MyClass(*args, **kwargs)

?

?

正如以上所示,一個類可以有多個位置參數和多個命名參數,而在實例化開始之后,在調用 __init__() 方法之前,Python 首先調用 __new__() 方法:

def __new__(cls, *args, **kwargs):...

  

第一個參數cls是當前正在實例化的類。

  • 如果要得到當前類的實例,應當在當前類中的 __new__() 方法語句中調用當前類的父類的 __new__() 方法。

  例如,如果當前類是直接繼承自 object,那當前類的 __new__() 方法返回的對象應該為:

def __new__(cls, *args, **kwargs):...return object.__new__(cls)

  

注意:

  事實上如果(新式)類中沒有重寫__new__()方法,即在定義新式類時沒有重新定義__new__()時,Python默認是調用該類的直接父類的__new__()方法來構造該類的實例,如果該類的父類也沒有重寫__new__(),那么將一直按此規矩追溯至object的__new__()方法,因為object是所有新式類的基類。

?

  而如果新式類中重寫了__new__()方法,那么你可以自由選擇任意一個的其他的新式類(必定要是新式類,只有新式類必定都有__new__(),因為所有新式類都是object的后代,而經典類則沒有__new__()方法)的__new__()方法來制造實例,包括這個新式類的所有前代類和后代類,只要它們不會造成遞歸死循環。具體看以下代碼解釋:

?

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__()方法,那么會自動調用其父類的__new__()方法來制造實例,即 Foo.__new__(cls, *args, **kwargs)。 # 在任何新式類的__new__()方法,不能調用自身的__new__()來制造實例,因為這會造成死循環。因此必須避免類似以下的寫法: # 在Foo中避免:return Foo.__new__(cls, *args, **kwargs)或return cls.__new__(cls, *args, **kwargs)。Child同理。 # 使用object或者沒有血緣關系的新式類的__new__()是安全的,但是如果是在有繼承關系的兩個類之間,應避免互調造成死循環,例如:(Foo)return Child.__new__(cls), (Child)return Foo.__new__(cls)。 class Stranger(object):... # 在制造Stranger實例時,會自動調用 object.__new__(cls)

?

?

  • ?通常來說,新式類開始實例化時,__new__()方法會返回cls(cls指代當前類)的實例,然后該類的__init__()方法作為構造方法會接收這個實例(即self)作為自己的第一個參數,然后依次傳入__new__()方法中接收的位置參數和命名參數。

?

注意:如果__new__()沒有返回cls(即當前類)的實例,那么當前類的__init__()方法是不會被調用的。如果__new__()返回其他類(新式類或經典類均可)的實例,那么只會調用被返回的那個類的構造方法。

?

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) # 打印的結果顯示foo其實是Stranger類的實例。# 因此可以這么描述__new__()和__ini__()的區別,在新式類中__new__()才是真正的實例化方法,為類提供外殼制造出實例框架,然后調用該框架內的構造方法__init__()使其豐滿。 # 如果以建房子做比喻,__new__()方法負責開發地皮,打下地基,并將原料存放在工地。而__init__()方法負責從工地取材料建造出地皮開發招標書中規定的大樓,__init__()負責大樓的細節設計,建造,裝修使其可交付給客戶。

?

單例的作用就是為了節約系統資源,每每生成一個對象的時候都回去占用內存空間,因此單例就可以結局這個問題 #非單例模式,非單例模式在每次實例化的時候都會去調用內存生,這樣調用的次數多了,就可能會造成內存的浪費class A(object):passa=A() b=A() print(id(a)) print(id(b))輸出結果 3000151570976 3000151571312#單例模式 #講解:在類開始之前會調用類的new方法去生成一個對象,所以我們只需要在類調用錢做處理就好了 class B(object):__instrance = None #定義一個變量def __new__(cls):if cls.__instrance == None:cls.__instrance = object.__new__(cls) #如果變量是None說明是第一次調用,就生成一個對象,return cls.__instranceelse:return cls.__instrance #如果不是就直接返回上次生成好了的對象c=B() d=B() print(id(c)) print(id(d))輸出結果 3000151571592 3000151571592#instrance :實例

總結:

__new__至少要有一個參數cls,代表要實例化的類,此參數在實例化時由Python解釋器自動提供

__new__必須要有返回值,返回實例化出來的實例,這點在自己實現__new__時要特別注意,可以return父類__new__出來的實例,或者直接是object的__new__出來的實例

__init__有一個參數self,就是這個__new__返回的實例,__init__在__new__的基礎上可以完成一些其它初始化的動作,__init__不需要返回值

我們可以將類比作制造商,__new__方法就是前期的原材料購買環節,__init__方法就是在有原材料的基礎上,加工,初始化商品環節
參考自http://www.cnblogs.com/ifantastic/p/3175735.html

總結

以上是生活随笔為你收集整理的python __new__中单例的作用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。