a = A()
print("show globals after create a")
print(globals()) # 从全局对象中能找到A() 'a': <__main__.A object at 0x7f04de263af0>
del a #
print("show globals after delete a")
print(globals()) # 这时全局对象中已经找不到对象A()了
time.sleep(1)
print("sleep end")
print(a) # 无法访问引用
输出结果:
show globals after create a
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f04de3de4c0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__cached__': None, 'time': <module 'time' (built-in)>, 'A': <class '__main__.A'>, 'a': <__main__.A object at 0x7f04de263af0>}
A instance deleted
show globals after delete a
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f04de3de4c0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__cached__': None, 'time': <module 'time' (built-in)>, 'A': <class '__main__.A'>}
sleep end
Traceback (most recent call last):
File "/testcode/mem.py", line 15, in <module>
print(a)
NameError: name 'a' is not defined
结果分析:
调完del命令,__del__
方法被执行,对象立即被删除(引用次数为0)。
实验2: 删除被多次引用的对象
在上面那个用例的基础上,用多个引用引用A的对象
删除其中一个引用,观察对象是否被删除
删除一个引用,只是那个引用被删除了,但是对象不会被删除。也就是__del__
方法不会被调用。
验证代码:
import time
class A:
def __del__(self):
print("delete instance of A")
a = A()
b = a
c = a
print("show globals after create a")
print(globals())
del a # 执行完这一行之后对象没有被回收,因为并没有打印出 delete instance of A
print("show globals after delete a")
print(globals()) # 在globals 里面还能找到对象 'b': <__main__.A object at 0x7fe1ef0c2af0>, 'c': <__main__.A object at 0x7fe1ef0c2af0> ,对象还没有被回收
time.sleep(1)
print("after sleeping...") # 打印完这句后 紧接着就打印了 delete instance of A ,也就是在 执行完 del b 和 del c 之后对象立即被回收了
del b
del c
print("show globals after delete b and c") # 执行到此处之前对象已经被回收
print(globals()) # 打印的globals里已经找不到对象 A()
输出结果:
show globals after create a
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fe1ef23d4c0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/testcode/mem.py', '__cached__': None, 'time': <module 'time' (built-in)>, 'A': <class '__main__.A'>, 'a': <__main__.A object at 0x7fe1ef0c2af0>, 'b': <__main__.A object at 0x7fe1ef0c2af0>, 'c': <__main__.A object at 0x7fe1ef0c2af0>}
show globals after delete a
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fe1ef23d4c0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/testcode/mem.py', '__cached__': None, 'time': <module 'time' (built-in)>, 'A': <class '__main__.A'>, 'b': <__main__.A object at 0x7fe1ef0c2af0>, 'c': <__main__.A object at 0x7fe1ef0c2af0>}
after sleeping...
delete instance of A
show globals after delete b and c
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fe1ef23d4c0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/testcode/mem.py', '__cached__': None, 'time': <module 'time' (built-in)>, 'A': <class '__main__.A'>}
结论:回收对象的方法
编程时候,一个创建一个对象我们最好只设置一个引用指向它,当不需要这个对象时候用del删除这个引用就可以回收对应的对象了。
以上实验在Python 3.8.12 和 Python 3.7.7 验证过。