python 中的 __init__ 和__new__方法的总结

__new __ 和 init 的区别和用法

使用类名()创建对象时,python解释器首先会调用__new__方法为对象分配空间。

__new__方法是一种静态方法有两个作用:1、分配空间;2、返回对象的引用。

init 方法作用: 1、对象的初始化;2、定义实例属性

只用__new__方法返回对象的引用时,python 解释器才能调用__init__方法 初始化对象。

重写__new__方法,是固定的格式,就是调用父类的__new__方法,返回给解释器。即:return super().new(cls)
在这里插入图片描述

​ 我们首先得从__new__(cls[,…])的参数说说起,__new__方法的第一个参数是这个类,而其余的参数会在调用成功后全部传递给__init__方法初始化,这一下子就看出了谁是老子谁是小子的关系。

所以,__new__方法(第一个执行)先于__init__方法执行:

class A:
    pass

class B(A):
    def __new__(cls):
        print("__new__方法被执行")
        return super().__new__(cls)
    def __init__(self):
        print("__init__方法被执行")
b = B()
        

执行结果为:

__new__方法被执行
__init__方法被执行

​ 我们比较两个方法的参数,可以发现__new__方法是传入类(cls),而__init__方法传入类的实例化对象(self),而有意思的是,__new__方法返回的值就是一个实例化对象(ps:如果__new__方法返回None,则__init__方法不会被执行,并且返回值只能调用父类中的__new__方法,而不能调用毫无关系的类的__new__方法)。我们可以这么理解它们之间的关系,__new__是开辟疆域的大将军,而__init__是在这片疆域上辛勤劳作的小老百姓,只有__new__执行完后,开辟好疆域后,__init__才能工作。

绝大多数情况下,我们都不需要自己重写__new__方法,但在当继承一个不可变的类型(例如str类,int类等)时,它的特性就尤显重要了。我们举下面这个例子:

class CapStr(str):
    def __init__(self,string):     
        string = string.upper()

a = CapStr("I love China!")
print(a)
 

执行结果为:

I love China!

class CapStr(str):
    def __new__(cls,string):
        string = string.upper()
        return super().__new__(cls,string)
 
a = CapStr("I love China!")
print(a)

执行结果为:

I LOVE CHINA!

​ 我们可以根据上面的理论可以这样分析,我们知道字符串 是不可改变的,所以第一个例子中,传入的字符串相当于已经被打下的疆域,而这块疆域除了将军其他谁也无法改变,__init__只能在这块领地上干瞪眼,此时这块疆域就是”I love China!“。而第二个例子中,__new__大将军重新去开辟了一块疆域,所以疆域上的内容也发生了变化,此时这块疆域变成了”I LOVE CHINA!“。__new__的作用】

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值