Python核心魔法方法(一)__init__ , __new__ 和__del__

谁是真正的构造函数

我们通常把__init__ 称为构造方法,这是从其他语言借鉴过来的术语。其实,用于构建实例的是特殊方法__new__:这是个类方法(使用特殊方式处理,因此不必使用@classmethod装饰器),必须返回一个实例。
返回的实例会作为第一个参数(即self)传给__init__ 方法。因为调用__init__ 方法时要传入实例,而且禁止返回任何值,

  • 所以__init__ 方法其实是“初始化方法”。 真正的构造方法是__new__。

我们几乎不需要自己编写__new__ 方法,因为从object 类继承的实现已经足够了。

实例创建过程

当使用"类名([实参])"创建实例对象时,Python解释器的主要处理过程包括2大步:
1.调用特殊方法__new__()创建实例对象
首先会查找该类对象是否实现了特殊方法__new__(),如果没有实现,则根据MRO顺序在父类中依次查找,直到类对象object
2.调用特殊方法__init__()返回创建的实例对象
new()返回的实例对象会作为实参被自动传递给__init__()的第一个形参self。
下面我们通过一个示例来展示这两大步,并且通过内置函数id( )来验证实例的创建过程。

class Parent(object):
    def __new__(cls, *args, **kwargs):
        print("父类的__new__()被调用,其形参cls对应实参的id:%s" % id(cls))
        obj = super().__new__(cls)  #此处通过super() 调用父类即object的new 方法
        print("创建的实例对象的id:%s" % id(obj))
        return obj  #将object 创建的实例对象返回,作为__init__接收的参数

class Child(Parent):
    def __init__(self, name):
        print("子类的__init__()被调用,其形参self对应实参的id:%s" % id(self))
        self.name = name

print("父类的id:%s" % id(Parent))
print("子类的id:%s" % id(Child))

child = Child("Mike")
print("创建的实例对象的id:%s" % id(child))

打印输出结果如下

父类的id2634116445304  #父类对象的id

子类的id2634116450968  #子类对象的id
父类的__new__()被调用,其形参cls对应实参的id:2634116450968  #对应实例创建的第1步 打印语句1,new接收的是一个类对象,同子类的id

创建的实例对象的id:2634151784064  ##对应实例创建的第1步 打印语句2
子类的__init__()被调用,其形参self对应实参的id2634151784064  #对应实例创建的第2步,接收的为第1步返回的实例对象
创建的实例对象的id2634151784064 #__init__外的实例对象,3者的id一样

实例的销毁

作为高级语言,python系统会自动销毁不再需要的对象以释放内存。如需要执行额外的清理工作,可以在自定义的类对象中实现特殊方法__del__( )。
这样,当内存中的对象被销毁(垃圾回收)之前,会自动调用器对应的特殊方法__del__( )。
示例代码如下

class MyClass(object):
    def __del__(self):
        print("特殊方法__del__被调用")

mc = MyClass()
del mc

注意!!!
此处仅作为示例,自己编写的代码很少需要实现__del__ 代码,有些Python 新手会花时间实现,但却吃力不讨好,因为__del__ 很难用对。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值