python中 __new__和__init__

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__只是在实例化之后用来修饰实例的

posted on 2014-04-23 17:55  kramer  阅读(289)  评论(0编辑  收藏  举报

导航