我们经常创建对象,但是一个对象完整的实例化过程包含哪些步骤?

三个魔法方法。

  • __new__ 对象的创建方法。object.__new__(cls[, ...]) 创建类cls的一个实例[1]。常见的实现方式是通过super(CLASSNAME, cls).__new__(cls, *args, **kwargs)获取实例,可能会修改实例并返回。
  • __init__ 对象的初始化方法。参数self__new__方法返回的实例。如果__new__ 返回的是cls的实例,新实例的__init__()方法会被调用;否则,不调用[2]。注意这里的返回实例所对应的__init__()
  • __call__ 类的对象可以像函数一样被调用[3]。

所以,一个类的实例化过程可以总结为[4]:

  1. 调用类A的__new__方法,获取返回的实例。
  2. 如果1中返回实例为A类实例,则调用实例的__init__方法,否则,不调用。

参考资料:


注[1]: 常见的__new__方法会返回所属类的实例,但是你也可以返回其他类的实例。下面例子中Bar类返回的是一个Out类的实例。

In [44]: class Out(object):
    ...:     def __init__(self):
    ...:         print(self.__class__, 'Out.__init__')
In [47]: class Bar(object):
    ...:     def __new__(cls):
    ...:         print(cls.__class__, 'Bar.__new__')
    ...:         return Out()

注[2]:

In [47]: class Bar(object):
    ...:     def __new__(cls):
    ...:         print(cls.__class__, 'Bar.__new__')
    ...:         return None
    ...:     def __init__(self):
    ...:         print(self.__class__, 'Bar.__init__')
In [48]: Bar()
<type 'type'> Bar.__new__

注[3]: __call__ 魔法方法举例

In [55]: class Hello(object):
    ...:     def __call__(self):
    ...:         print 'Say Hello'
In [56]: h = Hello()
In [58]: h()
Say Hello

注[4]: 无论是在__new__中还是在__init__中正常情况都应该明确的调用父类的__new____init__方法。如果子类中没有定义,直接调用父类的。