目录
1. __new__(cls[, ...])
__new__ 是对象实例化时调用的第一个方法,调用以创建一个 cls 类的新实例;
__new__ 将所请求实例所属的类作为第一个参数,即 cls 参数,其他参数会直接传给 __init__ 方法;
__new__ 通常不需要重写,默认执行即可;如果重写,一般用于允许不可变类型的子类 (例如 int, str 或 tuple) 定制实例创建过程,也常会在自定义元类中被重载以便定制类创建过程;
典型的实现会附带适宜的参数使用 super().__new__(cls[, ...]),通过父类的 __new__ 方法创建一个类的新实例,然后根据需要修改新创建的实例再将其返回。
#创建不可变类型 tuple 的子类
class Newtest(tuple):
#调用 __new__ 方法,改写子类在对象实例化时操作
def __new__(cls, inputtuple):
inputtuple = inputtuple + ('default element',)
#返回 super().__new__(cls[, ...]),通过父类的 __new__ 方法创建修改后子类的新实例
return super().__new__(cls, inputtuple)
#调用子类创建实例,执行成功
tuplex = (1,2,3)
tupley = Newtest(tuplex)
tupley
(1, 2, 3, 'default element')
2. __init__(self[, ...])
在实例(通过 __new__ 方法)被创建之后,返回调用者之前调用,其参数与传递给类构造器表达式的参数相同,相当于其他面向对象编程语言的构造方法;
实例对象由 __new__ 创建、__init__ 定制, 两个方法协作完成实例对象的构造,__init__ 返回值只能为 None,否则会在构造实例对象时报错;
如一个父类有重写的 __init__ 方法,其派生的子类如果也有重写 __init__ 方法,则需要在子类的 __init__ 方法中确保实例对象构造中父类部分的正确初始化,如添加 super().__init__([args...]) 代码段。
#创建类的 __init__ 方法有返回值
class Inittest():
def __init__(self, name):
self.name = name
return self.name
#构造实例对象时报错
testx = Inittest('abc')
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: __init__() should return None, not 'str'
#创建父类
class Inittest():
def __init__(self, name):
self.name = name
#创建不带父类初始化的子类1
class Initderived1(Inittest):
def __init__(self, value):
self.value = value
#创建带父类初始化的子类2
class Initderived2(Inittest):
def __init__(self, name, value):
super().__init__(name)
self.value = value
#子类1构建实例,调用父类初始化赋值变量失败
test1 = Initderived1('abc')
test1.name
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: 'Initderived1' object has no attribute 'name'
#子类2构建实例,调用父类、子类初始化赋值变量成功
test2 = Initderived2('wow','abc')
test2.name
'wow'
test2.value
'abc'
3. __del__(self)
__del__ 方法在实例将被销毁时调用,相当于其他面向对象编程语言的析构方法;
del object 不等于自动调用 object.__del__(),只有当垃圾回收机制回收这个对象时,才会调用 __dell__ 方法;即需要清除所有指向 object 实际地址的所有对象,开启垃圾回收机制, __dell__ 方法才开始执行;
当构建实例对象失败时,也会自动调用 __del__ 方法;
如一个父类有重写的 __del__ 方法,其派生的子类如果也有重写 __del__ 方法,则需要在子类的 __del__ 方法中确保删除实例对象时对其父类部分的正确析构,如添加 super().__del__(self) 代码段。
__del__ 方法可以(但不推荐!)通过创建一个该实例的新引用来推迟其销毁,这被称为对象重生。__del__() 是否会在重生的对象将被销毁时再次被调用是由具体实现决定的,当前的 CPython 实现只会调用一次。
#创建父类
class Deltest():
def __init__(self, name):
self.name = name
def __del__(self):
print(f'调用父类 del 方法')
#创建不带父类析构方法的子类
class Delderived1(Deltest):
def __del__(self):
print('调用子类1 del 方法')
#创建带父类析构方法的子类
class Delderived2(Deltest):
def __del__(self):
super().__del__()
print('调用子类2 del 方法')
#构建实例对象失败,调用 __del__ 方法
test1 = Deltest()
调用父类 del 方法
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: __init__() missing 1 required positional argument: 'name'
#调用不带父类析构方法的子类,没有执行父类 __del__ 方法
test1 = Delderived1('test1')
del test1
调用子类1 del 方法
#调用带父类析构方法的子类,执行父类 __del__ 方法
test2 = Delderived2('test2')
del test2
调用父类 del 方法
调用子类2 del 方法
#只有当垃圾回收机制回收这个对象时,才会调用 __dell__ 方法
test31 = Deltest('test')
test32 = test31
test33 = test32
del test31
del test33
del test32
调用父类 del 方法