实现和测试 __del__ 方法
在这一步,你将了解 __del__ 方法。这个方法被称为终结器(finalizer)或析构函数(destructor)。当一个对象的引用计数降为零时,它会被调用,这意味着它即将被 Python 的垃圾回收器(garbage collector)销毁。它通常用于清理任务,例如关闭网络连接或文件句柄。
你可以使用 del 语句来移除对一个对象的引用。当最后一个引用消失时,__del__ 会被自动调用。
让我们向 Dog 类添加一个 __del__ 方法,以查看对象何时被销毁。
再次打开 dog_cat.py 文件。用以下代码替换文件的全部内容。这个版本移除了创建 Dog 实例的代码(以避免在导入模块时创建它),并向 Dog 类添加了 __del__ 方法。
## File Name: dog_cat.py
class Animal:
def __init__(self, name):
self._name = name
def say(self):
print(self._name + ' is saying something')
class Dog(Animal):
def __new__(cls, name, age):
instance = super().__new__(cls)
return instance
def __init__(self, name, age):
super().__init__(name)
self.age = age
def say(self):
print(self._name + ' is making a sound: wang wang wang...')
## 将此方法添加到 Dog 类中
def __del__(self):
print(f'The Dog object {self._name} is being deleted.')
保存 dog_cat.py 文件。
现在,让我们创建一个单独的脚本来测试这种行为。从文件浏览器中打开文件 test_del.py。
将以下代码添加到 test_del.py 中。此脚本将创建两个 Dog 实例,然后显式删除其中一个。
## File Name: test_del.py
from dog_cat import Dog
import time
print("Creating two Dog objects: d1 and d2.")
d1 = Dog('Tom', 3)
d2 = Dog('John', 5)
print("\nDeleting reference to d1...")
del d1
print("Reference to d1 deleted.")
## 垃圾回收器可能不会立即运行。
## 我们添加一个短暂的延迟,给它一些时间运行。
time.sleep(1)
print("\nScript is about to end. d2 will be deleted automatically.")
保存文件。现在,在终端中运行 test_del.py 脚本。
python ~/project/test_del.py
观察输出。在调用 del d1 之后,会出现关于 Tom 的 __del__ 消息。关于 John 的消息出现在最后,因为当脚本结束时,d2 对象会被垃圾回收。
Creating two Dog objects: d1 and d2.
Deleting reference to d1...
The Dog object Tom is being deleted.
Reference to d1 deleted.
Script is about to end. d2 will be deleted automatically.
The Dog object John is being deleted.
注意:垃圾回收的确切时间可能会有所不同。__del__ 在对象被回收时调用,不一定是在使用 del 之后立即调用。