【问题标题】:Why is sys.argv set to None on exit in Python?为什么 sys.argv 在 Python 中退出时设置为 None?
【发布时间】:2020-08-12 13:50:58
【问题描述】:

请考虑以下脚本:

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()

我对运行此代码的期望是在 __init__()__del__()A 中打印相同的 sys.argv。但是,输出与预期不同:

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, ...)

我的问题:为什么会这样?这是 CPython 在关机时将 sys.argv 设置为 None 的实现细节,还是在文档中的某处进行了描述?为什么 Python(显式或通过 GC)首先从 sys 中删除一些对象(如 argvmeta_path),同时保留其他对象(如 float_info)?

我在 GNU/Linux 上使用 CPython 3.8.5。

【问题讨论】:

标签: python cpython internals


【解决方案1】:

在解释器关闭期间发生的__del__s 期间,解释器状态的所有保证或多或少都已关闭。

我有根据的猜测是模块和对象正在以任意顺序清理。如果您想深入研究,Py_FinalizeEx(void) here 似乎是调用所有其余部分的相关函数。

(无论如何,您都不应该依赖__del__ 进行确定性清理;例如,用户可能拥有gc.disable()d 并且您的函数将永远不会被调用。相反,请使用上下文管理器。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-03
    • 2020-10-17
    • 1970-01-01
    • 2017-05-17
    • 2018-07-20
    • 1970-01-01
    • 1970-01-01
    • 2014-11-05
    相关资源
    最近更新 更多