基于文章: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__是秘书给领导打工,后者领导的一众小弟们打工。