Python的对象实例化
我们经常创建对象,但是一个对象完整的实例化过程包含哪些步骤?
三个魔法方法。
__new__
对象的创建方法。object.__new__(cls[, ...])
创建类cls的一个实例[1]。常见的实现方式是通过super(CLASSNAME, cls).__new__(cls, *args, **kwargs)
获取实例,可能会修改实例并返回。__init__
对象的初始化方法。参数self
是__new__
方法返回的实例。如果__new__
返回的是cls的实例,新实例的__init__()
方法会被调用;否则,不调用[2]。注意这里的返回实例所对应的__init__()
。__call__
类的对象可以像函数一样被调用[3]。
所以,一个类的实例化过程可以总结为[4]:
- 调用类A的
__new__
方法,获取返回的实例。 - 如果1中返回实例为A类实例,则调用实例的
__init__
方法,否则,不调用。
参考资料:
- Python 2.7 reference data model
- 《编写高质量代码 改善Python程序的91个建议》 - 第55个
注[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__
方法。如果子类中没有定义,直接调用父类的。