Python魔法方法(一):构造与析构——__init__,__new__,__del__

看了小甲鱼的Python教程视屏后做的一些总结

init(self)

构造方法之一,用于初始化实例对象,在创建实例对象时将自动调用,可根据具体需求设置实例对象的一些属性:

class Ball:
   def __init__(self, name):
       self.name = name
   def call(self):
       print('我叫%s' % self.name)
a = Ball('球A')
a.call()

输出结果为:
‘我叫球A’
init(self)不能有返回值

new(cls[,…])

真正创建实例对象的方法,创建实例对象时将首先调用此方法进行实例对象的创建,然后再调用__init__方法对实例对象进行初始化。Object类中已对其进行了定义,它将通过一系列封装起来的操作完成对象的创建。
__new__方法一般不重写,如果单纯地对其重写:

class A:
   def __new__(cls):
       print('__new__方法被调用')
   def __init__(self):
       print('self方法被调用')
aaa = A()

此时,__init__将不被调用,仅输出 ‘__new__方法被调用’,而且实例对象aa也不存在(输入print(aa)将得到None)。
这是因为定义__new__方法时对A的父类Object中的__new__方法进行了重写,原有的用于创建实例对象的代码被覆盖,导致未能创建实例对象。
所以重写__new__方法通常会在返回值里调用其父类的__new__来保证实例对象的成功创建:

class A:
   def __new__(cls):
       print('__new__方法被调用')
       return super().__new__(cls)
   def __init__(self):
       print('self方法被调用')
aa = A()

new(cls[,…])中的cls默认指代当前类,它将创建cls类型的实例对象,而此实例对象将作为self传给__init__,也就是说,__new__创建的实例对象就是__init__的第一个参数self
__new__中cls后的参数也将作为__init__中self后的参数传入。但如果__new__创建的实例对象的类型不属于当前类,则当前类的__init__方法不会被调用:

class A:
   def __new__(cls):
       print('A--->New')
       return super().__new__(A)
   def __init__(self):
       print('A--->Init')
class B:
   def __new__(cls):
       print('B--->New')
       return super().__new__(A)
   def __init__(self):
       print('B--->Init')
aa = A()
bb = B()     

输出结果为:
A—>New
A—>Init
B—>New
A—>New
这里A的__new__方法返回了A类型的实例对象,所以A的__init__方法被调用,而B的__new__方法返回的为A类型的对象,所以B的__init__对象没有被调用(使用type(bb)可发现bb的类型为A),这里将return super().__new__(A)换为return super().__new__(cls)将可调用B的__init__方法

__new__方法中cls后的参数会自动传给__init__方法,如下:

class A:
    def __new__(cls, string):
        return super().__new__(cls, string)
   
   def __init__(self, string):
       print(string)
aaa = A('I love China!')

将输出 ‘I love China!’

一般很少重写__new__方法,但如果继承了一不可变类型(如字符串)却需要进行修改,则需重写,如下(小甲鱼课上举的例子):

class CapStr(str):
   def __new__(cls, string)
       string = string.upper()
       return str.__new__(cls,string)
a = CapStr('I love China')

这里将输出’I LOVE CHINA’,
即先将字符串改为大写,然后将修改后的字符串作为str__new__方法的一个参数传入,由str的__new__方法创建一个字符串类型的实例对象,所以使用type(a)查看实例对象a的类型可以发现a的类型为str(字符串)
这也是__new__方法的作用之一,即对一些不可变类型在其未被创建时做出需要的修改

del(self)

析构器,当一个对象要被销毁时会自动调用__del__(self),但del x并不等于自动调用x.__del__(),即当垃圾回收机制认定对象无用将要回收时,才会自动调用__del__(self)(当del删除了一个对象的所有引用,将自动启动__del__(self))

class A:
   def __del__(self):
       print('A--->Del')
a1 = A()
a2 = A()
a3 = A()
del a1
del a2
del a3      # 仅在此句被执行后打印'A--->Del'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值