Python中__new__和__init__的区别与联系

Python中__new__和__init__的区别与联系

Python中__new__和__init__的区别与联系

只有继承自object的新式类才有__new__方法

主要区别:
__new__负责对象的创建,如:为对象分配空间
__init__负责对象的初始化,如:初始化成员变量

调用时间:
__new__:创建对象时自动调用执行,会返回当前类的一个实例对象
__init__:对象创建完成后自动调用执行,无返回值

1. 在类中,如果__new__和__init__同时存在,会优先调用__new__

class ClsTest(object):
    def __init__(self):
        print("init")
    def __new__(cls,*args, **kwargs):
        print("new")
  
ClsTest()

输出结果:new

2. 如果__new__返回一个对象的实例,会隐式调用__init__

代码如下:

class ClsTest(object):
    def __init__(self):
        print("init")

    def __new__(cls, *args, **kwargs):
        print("new")
        return object.__new__(cls, *args, **kwargs)

c1 = ClsTest()

输出结果为:

new
init

可以看到我们在重写的new方法中没有调用init方法,但是依然打印出了init,但是只要new返回一个对象,init方法就会自动调用执行吗?看下一个问题

3. 若__new__没有正确返回当前类cls的实例,那__init__是不会被调用的,即使是父类的实例也不行

class ClsTest1(object):
    pass
  
class ClsTest2(ClsTest1):
    def __init__(self):
        print ("init")
    def __new__(cls,*args, **kwargs):
        print ("new %s"%cls)
        return object.__new__(ClsTest1, *args, **kwargs)
  
b=ClsTest2()
print (type(b))

结果:

new <class '__main__.ClsTest2'>
<class '__main__.ClsTest1'>

在执行new方法时打印了本类cls,输出new <class '__main__.ClsTest2'>,创建了对象b,再打印b的类型为<class '__main__.ClsTest1'>,可以看到创建的是父类的一个对象,不是本类的,所以init方法没有执行.