Python的关闭过程将模块globals设置为None documented在哪里?

2024-04-25 18:53:05 发布

您现在位置:Python中文网/ 问答频道 /正文

CPython有一种奇怪的行为,它在关机时将模块设置为“无”。在我编写的一些多线程代码关闭期间,这会导致错误日志记录出错

我找不到任何关于这种行为的文件。在PEP 432中顺便提到:

[...] significantly reducing the number of modules that will experience the "module globals set to None" behaviour that is used to deliberate break cycles and attempt to releases more external resources cleanly.

SO questions about this behaviourC API documentation mentions shutdown behaviour for embedded interpreters

我还发现了一个related thread on python-dev和一个related CPython bug

This patch does not change the behavior of module objects clearing their globals dictionary as soon as they are deallocated.

这种行为记录在哪里?它是Python 2特有的吗


Tags: 模块oftheto代码thatas错误
2条回答

这种行为没有得到很好的记录,并且在从大约1.5-ishPython 3.4的所有Python版本中都存在:

As part of this change, module globals are no longer forcibly set to None during interpreter shutdown in most cases, instead relying on the normal operation of the cyclic garbage collector.

该行为的唯一文档是^{} source code

/* To make the execution order of destructors for global
   objects a bit more predictable, we first zap all objects
   whose name starts with a single underscore, before we clear
   the entire dictionary.  We zap them by replacing them with
   None, rather than deleting them from the dictionary, to
   avoid rehashing the dictionary (to some extent). */

注意,将值设置为None是一种优化;另一种方法是从映射中删除名称,这将导致不同的错误(NameError异常,而不是AttributeError__del__处理程序中使用全局变量)

正如您在mailinglist上发现的,这种行为早于循环垃圾收集器;它是added in 1998,而循环垃圾收集器是added in 2000。由于函数对象总是引用模块__dict__,因此模块中的所有函数对象都涉及循环引用,这就是为什么__dict__需要在GC发挥作用之前清除的原因

即使添加了循环GC,它也会保持在原位,因为循环中可能涉及到具有__del__方法的对象。这些aren't otherwise garbage-collectable和清除模块字典将至少从这些循环中删除模块__dict__。不这样做将使该模块的所有引用全局保持活动状态

PEP 442所做的更改现在使垃圾收集器可以清除具有提供__del__终结器的对象的循环引用,从而消除了在大多数情况下清除模块__dict__的需要。代码为still there,但仅当__dict__属性仍然处于活动状态时,才会触发该代码,即使在解释器关闭时,将sys.modules的内容移动到弱引用并启动GC收集运行之后也是如此;模块终结器只是减少它们的引用计数

bottom of the threading docs有少量相关文件:

Secondly, all import attempts must be completed before the interpreter starts shutting itself down. [..] Failure to abide by this restriction will lead to intermittent exceptions and crashes during interpreter shutdown (as the late imports attempt to access machinery which is no longer in a valid state).

相关问题 更多 >