1. 概念
在Python中,所有以双下划线__
包起来的方法,统称为Magic Method(魔术方法),它是一种的特殊方法。
2. 构造和初始化
最基本的魔术方法,大家经常用的__init__ 。这是我们初始化定义的对象行为的方式。但是当我实例化一个类 instance = MyClass() 时,__init__ 并不是第一个被叫到的。而是令一个方 法__new__,由它实际上创建了实例,然后将创建时的任何参数传递给初始化程序。在对象生命周期的另一端,是__del__方法。
我们仔细看看这 3 个魔术方法:
-
__new__(cls, ...):__new__是在对象的实例化中调用的第一个方法。注意:这里的第一个参数是cls即class本身,然后是它将传递给它的其他参数透传给 __init__ 。 __new__其实很少使用,但它确实有其用途,特别是在子类化不可变类型(如元组或字符串)时。、
-
__init__(self, ...):- 实例的初始化。无论主构造函数是用什么调用的,它都会被传递(因此,例如,如果我们调用 instance = MyClass(10,’a‘), 10和’a‘将被传递给 __init__ 。 可以把instance = MyClass(10,’a‘) 理解为
instance = MyClass.__new__() instance = instance.__init__(10, 'a')
-
__del__(self) : __new__和 __init__ 形成了对象的构造函数, __del__ 就是解构函数。但是它不实现语句的行为del x(因此代码不会转换为
x.
__del__())。相反,它定义了对象被垃圾收集时的行为。它对于删除时可能需要额外清理的对象非常有用,例如套接字或文件对象。但是要小心,因为无法保证 __del__在解释器退出时对象仍然存在时会被执行,因此 __del__不能替代良好的编码实践(例如在完成时总是关闭连接)。 需要谨慎使用!
代码示例:
class MyClass:
def __new__(cls, *args, **kwargs):
print(f"new {cls}")
return object.__new__(cls)
def __init__(self, a, b):
self.a = a
self.b = b
my = MyClass(12, 22)
new <class '__main__.MyClass'>
示例2 使用__del__
from os.path import join
class FileObject:
def __init__(self, filepath='~', filename='sample.txt'):
self.file = open(join(filepath, filename), 'rb')
def __del__(self):
# 确保删除文件对象时, 文件是关闭的
self.file.close()
del self.file