问题描述
请考虑以下脚本:
import sys
class A:
def __init__(self):
print('Constructing A')
print(sys.argv)
print(sys.meta_path)
print(sys.float_info)
def __del__(self):
print('Destructing A')
print(sys.argv)
print(sys.meta_path)
print(sys.float_info)
x = A()
我希望通过运行此代码将在类sys.argv
的{{1}}和__init__()
中打印相同的__del__()
。但是,输出不同于预期:
A
我的问题:为什么会这样? CPython是在关机时将Constructing A
['test.py']
[<class '_frozen_importlib.BuiltinImporter'>,...]
sys.float_info(max=1.7976931348623157e+308,...)
Destructing A
None
None
sys.float_info(max=1.7976931348623157e+308,...)
设置为sys.argv
的实现细节吗?还是在文档中的某个地方进行了描述?为何Python(显式或通过GC)首先从None
中删除某些对象(如sys
或argv
),而保留其他对象(如meta_path
)呢?
我正在GNU / Linux上使用CPython 3.8.5。
解决方法
在解释器关闭期间发生的__del__
期间,所有关于解释器状态的保证都会或多或少地消失。
我有根据的猜测是,模块和对象以任意顺序被清理。如果您想深入研究,Py_FinalizeEx(void)
here似乎是调用所有其余函数的相关函数。
(无论如何,您都不应该依赖__del__
进行确定性清理;例如,用户可能已经gc.disable()
d被使用,并且您的函数将永远不会被调用。而是使用上下文管理器。)>