python这两个函数和类的实例化有关。
__init__是实例化完成之后调用的,会对生成的对象实例做一些修饰
__new__是python新类型才有的,它更像是c/c++里面的构造函数,因为这个函数会返回一个合法的实例。
看下面的例子
>>> class A(object): ... pass ... >>> class B(A): ... def __init__(self): ... print '__init__ running' ... def __new__(cls,*args, **kwargs): ... print "new %s" %cls ... print '__new__ running' ... return object.__new__(A, *args, **kwargs)
我们先生成了一个类A, 然后根据类A生成了一个类B。 注意B中定义了 __init__函数,它什么也没敢,只是打印一句话证明自己在运行,当然你可以在里面加一些别的操作。 而__new__函数就需要仔细注意一下了。这个__new__函数显示打印了当前的cls。 这个cls是像self一样在调用的时候不需要显示传给的。cls是当前的类,我们在__new__中把将其打印出来,这样你就能更直观的明白cls是什么。 然后我们打印一句话证明__new__在运行,再然后我们调用 object的new来返回一个值。注意这里调用的第一个参数是A,也就是说返回的对象是类型A的。
然后我们运行一下下面的代码。
>>> b=B() new <class '__main__.B'> __new__ running
b=B() 会调用B中的__new__()。 两行输出我们可以看到。但是我们知道__init__函数是在实例化之后被调用的,这里似乎没有调用__init__。 这是为什么呢? 因为我们B类中的__new__返回的类型是A类型。 __new__如果返回的不是当前类 cls 的实例,那么 __init__ 是不会被调用的。 我之前想,也许因为返回的是A类型的实例,那么如果A类型有__init__ 也许就会调用A类型的__init__。 事实证明也不会。
ok.我们把B类改一下,让其__new__返回cls 也就是当前类的实例。
>>> class B(A): ... def __init__(self): ... print '__init__ running' ... def __new__(cls,*args, **kwargs): ... print "new %s" %cls ... print '__new__ running' ... return object.__new__(cls, *args, **kwargs) ... >>> b=B() new <class '__main__.B'> __new__ running __init__ running
可以看到是 __new__先运行 然后 __init__运行。 从这里也可以知道 __new__更类似于构造函数,而__init__只是在实例化之后用来修饰实例的