python里__init__方法和__new__方法的区别

2019-10-29  本文已影响0人  夏2018
这里我们定义一个A类

class A(object):
    def __new__(cls, *args, **kwargs):
        print("new func is called ...")

    def __init__(self):
        print("init func is called ...")

    def __str__(self):
        return "A"
        
print(A())


#输出结果:
new func is called ...
None

#分析
这里我们看到new方法执行了,init方法没有执行,因为new方法里只是做简单的打印,这说明init方法执行很可能依赖new方法

这里把代码稍微修改下,在new方法里添加 return super(A,cls).__new__(cls)

class A(object):
    def __new__(cls, *args, **kwargs):
        print("new func is called ...")
        return super(A,cls).__new__(cls)

    def __init__(self):
        print("init func is called ...")

    def __str__(self):
        return "A"

print(A())

#输出结果:
new func is called ...
init func is called ...
A

#分析:
这里我们很明显可以看到init的方法和new方法里的super调用有关系,new方法的调用是发生在init之前的,调用new方法会返回一个创建好A实例赋值给init方法里的self,然后init会被调用
我们再看一种写法

class A(object):
    def __new__(cls):
        print("new func is called ...")
        instance = super(A, cls).__new__(cls)
        instance.__init__()
        return 5

    def __init__(self):
        print("init func is called ...")
        
    def __str__(self):
        return "A"

i = A()
print(i)

#输出结果:
new func is called ...
init func is called ...
5

#分析:
这里我们手动调用了init方法,这样无需返回创建的示例也可以产生对象,里我们看到其实打印的就是new返回的结果,之前没有手动调用init方法打印的对象是A因为new方法里返回的是A的实例
我们再把代码修改下

class A(int):
    def __new__(cls,a):
        print("new func is called ...")
        return super(A, cls).__new__(cls,abs(a))

    def __init__(self,a):
        super(A, self).__init__(self, a)
        print("init func is called ...")
        

i = A(-3)
print(i)

#输出结果:
new func is called ...
init func is called ...
3

#分析:
依照Python官方文档的说法,new方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径
上一篇 下一篇

猜你喜欢

热点阅读