Python 当解释器关闭时,对象会发生什么情况

Python 当解释器关闭时,对象会发生什么情况,python,Python,当Python解释器关闭时,我对对象发生了什么感到有点困惑。 如果我写一段这样的代码 class MyClass(object): def __del__(self): print "I'm going away" o = MyClass() 运行它,我会得到这个 I'm going away 我的理解是,当解释器关闭时,它将删除对已创建对象的所有引用,如果指定,这些对象将运行\uu del\uu()(因为它们的引用计数为0) 我的困惑是: 我找不到任何说明pyth

当Python解释器关闭时,我对对象发生了什么感到有点困惑。 如果我写一段这样的代码

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

o = MyClass()
运行它,我会得到这个

I'm going away
我的理解是,当解释器关闭时,它将删除对已创建对象的所有引用,如果指定,这些对象将运行
\uu del\uu()
(因为它们的引用计数为0)

我的困惑是:

  • 我找不到任何说明python将在退出时清除所有引用的文档
  • 我不明白为什么它会在内存即将返回操作系统并声明为可用时清理对象。我猜在复杂的系统中,删除内存中即将免费的对象会有很大的成本
  • 阅读有关
    \uuu del_uu()
    的文档时,我看到了
    不能保证当解释器退出时仍然存在的对象会调用\uu del_uu()方法。
    而且它变得有点复杂,他们是说由于一些循环依赖性而不能保证运行,还是说不能保证?谁来决定
  • 因此,我的问题是:

  • 在我上面的例子中,谁调用了
    \uu del\uu
  • 为什么当我没有引用循环时不能保证调用它

  • 我不明白第一个问题的要点,但是对于CPython 2.7.8,
    \uu del\uuu
    PyInstanceObject.instance\u dealloc
    调用,它注册为
    tp\u dealloc
    ,在调用
    Py\u DECREF
    且引用计数为零时调用。所以,让我们假设解释器调用它,而不是Python代码。如果你问这个问题的目的是希望你能改变它被呼叫的方式或时间,我认为这是不可能的

    至于为什么不能保证,要做到这一点,您必须在退出之前通过所有模块删除它们的变量,但是如果
    \uuu del\uuu
    方法依赖于任何全局变量,就没有简单的方法来保证它们执行的安全顺序。我不是说这是不可能的,就像引用周期一样,我是说它很复杂


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

    不确定你在问什么。您引用的文档说,当解释器退出时,不能保证对存在的对象调用
    \uuu del\uu
    。不仅仅是那些参考周期;没有。一般来说,你不能假设你的
    \uuu del\uu
    方法会被调用。我想我要问两个问题,首先,在我上面的例子中谁调用了del,第二个原因是,当我没有循环时,它不能得到保证。文档的意思是,解释器退出时,存在的对象可能会调用
    \uuu del\uu
    。在你的案例中,它看起来是被称为,但这基本上是运气;你不能指望它会被调用或不被调用。至于你的第二个问题,我不知道技术原因,但事实就是这样。文档很清楚,这就是它的工作原理。
    \uu del\uu
    可用于在文件关闭前完成文件结尾的写入。BrenBarn说这些终结器被认为不可靠是正确的,所以这样做有点反模式,但这不仅仅是运气——如果你有一个引用循环,GC不知道在这个循环中哪个对象(如果有的话)可以安全地首先清理。如果您知道不可能有引用周期(在数据结构之外很少有),那么就不会有问题。C++不提供GC,所以可以用它自己的但书提供可靠的析构函数清理。也不想给竞争的实现添加另一个严格的负担。你是说这是一个假设,还是你知道是这样的?毫无疑问,这是有道理的,但我不知道当时是否考虑过这一点。