解释器关闭时对象会发生什么

Ale*_*tin 8 python

当Python解释器关闭时,我对对象发生了什么感到困惑.如果我写一些类似的代码

class MyClass(object):
    def __del__(self):
        print "I'm going away"

o = MyClass()
Run Code Online (Sandbox Code Playgroud)

并运行它,我会得到这个

I'm going away
Run Code Online (Sandbox Code Playgroud)

我的理解是,当解释器关闭时,它将删除对创建对象的所有引用,__del__()如果指定了这些对象将运行(因为它们的引用计数为0).

我的困惑是因为:

  1. 我无法找到任何文档说python将在退出时清除所有引用.
  2. 我很困惑为什么当内存即将返回操作系统并且无论如何都被宣布为空闲时它正在清理对象.我想在复杂的系统中,删除内存中即将是免费的对象的成本很高.
  3. 阅读有关__del__()我看到的文档It is not guaranteed that __del__() methods are called for objects that still exist when the interpreter exits.并且它变得有点复杂,他们是否说由于某些循环依赖性而无法保证可以运行它或者它不能保证?是谁决定的?

所以我的问题是:

  1. 谁打电话给__del__我上面的例子
  2. guaranteed当我没有参考周期时,为什么不调用它

Ped*_*eck 2

我不明白第一个问题的要点,但对于 CPython 2.7.8,__del__is 被 调用PyInstanceObject.instance_dealloc,它被注册为tp_dealloc,当被Py_DECREF调用并且引用计数达到零时被调用。所以,我们就说解释器调用它,而不是 Python 代码。如果您问这个问题是希望可以更改调用方式或时间,我认为这是不可能的。

至于为什么不能保证,要做到这一点,您必须在退出之前遍历所有模块并删除其变量,但如果这些方法__del__依赖于任何全局变量,则没有简单的方法来保证它们的执行顺序。我并不是说这是不可能的,就像引用循环一样,我是说它很复杂。

我想这个问题曾经在某个时候被讨论过,但社区或 BDFL 认为不值得这么麻烦。我相信几年前我看到过一些关于这个问题的讨论,但现在找不到了。从一开始就不鼓励使用该__del__方法,如果您需要保证调用某些析构函数方法,那么最好使用上下文管理器。