一、__init__和__new__方法執行的順序?
在面向對象中介紹了關於對象創建的過程,我們知道__new__方法先於__init__方法執行。
二、__new__方法是什么?
首先,我們先來看下下面的代碼
class person(object): def __init__(self,name,age): self.age=age self.name=name print('exec init....') def __new__(cls, *args,**kwargs): print('exec new....') return super(person,cls).__new__(cls) obj1=person('wd',22) 執行結果: exec new.... exec init....
上面代碼告訴了我們,執行init之前new方法執行了,並且代碼中重構了父類的new方法,在上一篇面向對象過程中解釋了類創建過程,執行new的過程就是person類創建的過程,所以__new__方法實際上就是創建這個類實例方法。(這里指的是person類)
說明下上述代碼的執行過程:
1.當解釋器解釋到obj1=person('wd',22)時候,先執行__new__(cls,*args,**kwargs),並執行父類的__new__方法,將name,age參數傳入父類__new__方法,創建person。
2.類創建完成以后,在調用__init__方法,將wd和22參數傳入創建對象。
三、__init__與__new__的區別
從上述過程中我們可以發現,這兩個方法區別在於:
1.__init__ 通常用於初始化一個新實例,控制這個初始化的過程,比如添加一些屬性, 做一些額外的操作,發生在類實例被創建完以后。它是實例級別的方法。
2.__new__ 通常用於控制生成一個類實例的過程。它是類級別的方法。
四、__new__的作用
依照Python官方文檔的說法,__new__方法主要是當你繼承一些不可變的class時(比如int, str, tuple), 提供給你一個自定義這些類的實例化過程的途徑。還有就是實現自定義的metaclass。
首先我們來看一下一個功能,自定義類似int類功能,使用int類整數化以后將數變為非負數(大於0)。
class myint(int): def __new__(cls, *args,**kwargs): print('exec new....') return super(myint,cls).__new__(cls,abs(*args)) print(myint(-1))#自定義int類 print(int(-1))#自帶的int類 結果: exec new.... 1 -1
五、通過__new__方法實現單實例
單例模式,可以簡單理解為實例化后生成的每個實例都是完全一樣的。
class Single(object): def __new__(cls): if not hasattr(cls, 'myinstance'): cls.myinstance = super(Single, cls).__new__(cls) return cls.myinstance#每次生成的都是同一個實例 obj1 = Single() obj2 = Single() obj1.attr1 = 'wd' print(obj1.attr1, obj2.attr1) print(obj1 is obj2)#返回True表明是同一個實例 結果: wd wd True