如何在Python中销毁一个对象?
当一个对象被删除或销毁时,会调用一个 析构函数 。在终止一个对象之前,使用析构函数完成清理任务,如关闭数据库连接或文件句柄。
Python中的垃圾收集器自动管理内存。例如,当一个对象不再相关时,它会清空内存。
在Python中,析构函数是完全自动的,从不手动调用。在以下两种情况下,析构函数会被调用:
- 对象不再相关,或者超出其作用域;
- 对象的引用计数达到零。
阅读更多:Python 教程
使用del()方法
在Python中,可以使用特定函数del()来定义析构函数。例如,当我们运行 del object name 时,对象的析构函数会自动调用,并在此之后通过垃圾回收将其销毁。
示例1
以下是使用del()方法定义析构函数的示例 –
# 创建一个名为destructor的类
class destructor:
# 初始化这个类
def __init__(self):
print ("对象被创建");
# 调用析构函数
def __del__(self):
print ("对象被销毁");
# 创建一个对象
Object = destructor();
# 删除对象
del Object;
输出
以下是上面代码的输出 -
对象被创建
对象被销毁
注意 - 上述代码中的析构函数在程序运行完毕后或引用对象被删除时调用。这表明对象的引用计数现在已经降为零,而不是在离开作用域时。
示例2
在以下示例中,我们将使用Python的del关键字销毁用户定义的对象 –
class destructor:
Numbers = 10
def formatNumbers(self):
return "@" + str(Numbers)
del destructor
print(destructor)
输出
以下是上面代码的输出 -
NameError: name 'destructor' is not defined
我们得到上述错误是因为‘destructor’已被销毁。
示例3
在以下示例中,我们将看到 –
- 如何使用析构函数;
- 当我们删除对象时,如何调用析构函数?
class 析构函数:
# 使用构造函数
def __init__(self, name):
print('在构造函数中')
self.name = name
print('对象已被初始化')
def show(self):
print('名字是', self.name)
# 使用析构函数
def __del__(self):
print('在析构函数中')
print('对象正在被销毁')
# 创建一个对象
d = 析构函数('被摧毁')
d.show()
# 删除对象
del d
输出
我们使用上面的代码创建了一个对象。使用引用变量d来标识新生成的对象。当对象的引用被销毁或引用计数为0时,析构函数被调用。
在构造函数中
对象已被初始化
名字是被摧毁
在析构函数中
对象正在被销毁
析构函数的注意事项
- 当一个对象的引用计数为0时,会为该对象调用del方法。
- 当应用关闭或我们手动使用del关键字删除所有引用时,该对象的引用计数将降为零。
- 当我们删除对象引用时,析构函数不会被调用。直到所有对该对象的引用都被删除,它才会运行。
示例
让我们使用示例来掌握上述原理−
- 首先使用d = 析构函数(“被摧毁”)为学生类创建一个对象。
- 接下来,使用d1=d将对象引用d赋值给新对象d1。
- 现在,同一对象被d和d1变量引用。
- 然后,我们删除引用d。
- 为了了解析构函数只有在销毁对象的所有引用时才运行,我们在主线程中添加了10秒的休眠时间。
import time
class destructor:
# 使用构造函数
def __init__(self, name):
print( '构造函数内部')
self.name = name
print( '对象已初始化')
def show(self):
print('名称为', self.name)
# 使用析构函数
def __del__(self):
print('析构函数内部')
print('对象已被销毁')
# 创建一个对象
d = destructor('已销毁')
# 创建新引用,两个引用都指向同一个对象
d1=d
d.show()
# 删除d对象
del d
# 添加延时以观察输出
time.sleep(10)
print('延时10秒后')
d1.show()
输出结果
可以看到,只有在所有对象的引用都被删除后,析构函数才会被调用。
此外,一旦程序运行结束并且对象已准备好被垃圾回收器处理时(也就是说,我们没有显式使用del d1来删除对象引用d1),析构函数会被调用一次。
构造函数内部
对象已初始化
名称为已销毁
延时10秒后
名称为已销毁