基於文章:Why is init() always called after new()?code
特別說明:對象
這篇文章的靈感來源於stackoverflow的一個提問,準確說,我只是作了些知識梳理的工做,對其中的優秀回答進行了總結和提煉,旨在幫助本身和讀者對此有個深入的認識。內存
本文章節中的new是__new__
的簡寫,init是__init__
的簡稱,只是爲了語言敘述的方便而作出的省略。get
new是靜態的類方法,static method。
init是實例方法。it
它們有不一樣的參數與返回值:io
class B(object): _dict = dict() def __new__(cls): if 'key' in B._dict: print("EXISTS:", B._dict['key']) return B._dict['key'] else: print("NEW") return super(B, cls).__new__(cls) def __init__(self): print("INIT") B._dict['key'] = self print("") b1 = B() b2 = B() b3 = B() # 運行結果以下: NEW INIT EXISTS: <__main__.B object at 0x0000028F29820828> INIT EXISTS: <__main__.B object at 0x0000028F29820828> INIT
關於原文中的代碼解釋:class
在每次實例化以前,也就是new的操做時,都查詢了是否存在第一個實例。在第一次初始化時,把第一個實例self賦值給了類的公有屬性:test_dict。以後的每次實例化以前,new都會查詢到它(實例)已經存在,new而且老是返回了第一個實例給了init。而後init參與對該實例(老是第一個實例)進行構建工做。test
我只能揣測,原問題的做者彷佛意外建立了一個單例的類。你能夠在init中執行print(self),會發現打印出來的對象老是第一個實例。固然,若是確實是想要實現單例模式,應該使用裝飾器。即:object
def singleton(cls): instances = {} def getinstance(): if cls not in instances: instances[cls] = cls() return instances[cls] return getinstance @singleton class MyClass: ...
爲何instances使用的是字典?由於Python老是用字典去存儲一個新的實例,而且init中的屬性也一樣以字典的方法存儲的。固然,若是你想節約內存,不使用字典而用列表,能夠重載new方法,或者使用__slot__
。方法
class A(object): test_dict = dict() def __new__(cls): if 'key' in A.test_dict: print("EXISTS:", A.test_dict['key']) return A.test_dict['key'] else: print("NEW") return super(A, cls).__new__(cls) def __init__(self): print("INIT") if 'key' in A.test_dict: print('修改') A.test_dict['key'] += 1 else: print('第一次建立') A.test_dict['key'] = 0 print('') a1 = A() a2 = A() a3 = A()
class A(object): test_dict = dict() 1.類的公有屬性 def __new__(cls): 2.執行__new__ if 'key' in A.test_dict: print("EXISTS:", A.test_dict['key']) return super(A, cls).__new__(cls) else: print("NEW") return super(A, cls).__new__(cls) def __init__(self): print("INIT") if 'key' in A.test_dict: print('修改') A.test_dict['key'] += 1 else: print('第一次建立') A.test_dict['key'] = 0 print('') a1 = A() a2 = A() a3 = A()
精要:
它們負責的工做不一樣:前者負責建立新實例,後者負責實例初始化
它們服務的層級不一樣:前者是cls(類),後者是self(實例自己)
__new__是祕書給領導打工,後者領導的一衆小弟們打工。