Python新类中的__new__
和__init__
Python的新类允许用户重载__new__
和__init__
方法,且这两个方法具有不同的作用。__new__
作为构造器,起创建一个类实例的作用。而__init__
作为初始化器,起初始化一个已被创建的实例的作用。
如下面代码是所示:
class newStyleClass(object): # In Python2, we need to specify the object as the base. # In Python3 it's default. def __new__(cls): print("__new__ is called") return super(newStyleClass, cls).__new__(cls) def __init__(self): print("__init__ is called") print("self is: ", self) newStyleClass()
结果如下:
__new__ is called __init__ is called self is: <__main__.newStyleClass at 0x109290890> <__main__.newStyleClass at 0x109290890>
创建类实例并初始化的过程中__new__
和__init__
被调用的顺序也能从上面代码的输出结果中看出:__new__
函数首先被调用,构造了一个newStyleClass
的实例,接着__init__
函数在__new__
函数返回一个实例的时候被调用,并且这个实例作为self
参数被传入了__init__
函数。
这里需要注意的是,如果__new__
函数返回一个已经存在的实例(不论是哪个类的),__init__
不会被调用。如下面代码所示:
obj = 12 # obj can be an object from any class, even object.__new__(object) class returnExistedObj(object): def __new__(cls): print("__new__ is called") return obj def __init(self): print("__init__ is called") returnExistedObj()
执行结果如下:
__new__ is called 12
同时另一个需要注意的点是:
如果我们在__new__
函数中不返回任何对象,则__init__
函数也不会被调用。
如下面代码所示:
class notReturnObj(object): def __new__(cls): print("__new__ is called") def __init__(self): print("__init__ is called") print(notReturnObj())
执行结果如下:
__new__ is called None
可见如果__new__
函数不返回对象的话,不会有任何对象被创建,__init__
函数也不会被调用来初始化对象。
总结几个点
__init__
不能有返回值__new__
函数直接上可以返回别的类的实例。如上面例子中的returnExistedObj
类的__new__
函数返回了一个int
值。- 只有在
__new__
返回一个新创建属于该类的实例时当前类的__init__
才会被调用。如下面例子所示:
class sample(object): def __str__(self): print("sample") class example(object): def __new__(cls): print("__new__ is called") return sample() def __init__(self): print("__init__ is called") example()
输出结果为:
__new__ is called sample
如果对于参考答案有不认同的,大家可以在评论区指出和补充,欢迎留言!