【发布时间】:2012-09-21 22:26:39
【问题描述】:
我希望我的 Python 程序具有确定性,因此我一直在整个代码中广泛使用 OrderedDicts。不幸的是,今天在调试内存泄漏时,我发现 OrderedDicts 有一个自定义的__del__ 方法,只要有循环就无法收集它们。不幸的是,文档中没有关于此的警告。
那我该怎么办? Python 标准库中是否有任何与 gc 配合得很好的确定性字典?我真的不想自己动手,尤其是像这样愚蠢的单行函数。
另外,我应该为此提交错误报告吗?我不熟悉 Python 库的过程,以及他们认为的错误。
编辑:It appears that this is a known bug that was fixed back in 2010. I must have somehow gotten a really old version of 2.7 installed. 我想最好的方法是只包含一个猴子补丁,以防用户碰巧运行像我这样的损坏版本。
【问题讨论】:
-
首先,您使用的是什么版本的 Python?看看 CPython 2.7,
collections.OrderedDict是纯 Python,它根本没有自定义 del 方法。 -
另外,你到底想在这里完成什么?标准的
dict实际上是确定性的——一遍又一遍地运行同一个程序,并且顺序总是相同的。它不是可预测的(没有大量内部知识,或者只运行一次就可以看到你得到了什么),但是为什么你需要顺序是可预测的? -
即使这是你需要的,你也不需要自己动手;
OrderedDict的文档(在 2.7 和 3.3 中)具有指向“在 Python 2.4 或更高版本上运行的等效 OrderedDict 配方”的链接,并且没有 del;你有什么理由不能使用它吗? -
最后,Python 可以使用自定义
__del__方法打破对象的循环,它只需要帮助——你必须查看gc.garbage并为它打破循环(然后将其从 @987654329 中删除@, 当然)。这通常是您不想做的事情,但是如果您正在编写循环并且取决于 gc,您将不得不在某个时候学习。 (或者,当然,您可以停止编写周期,例如,使用weakrefs。) -
@abarnert 我正在运行 CPython 2.7,我的版本确实有一个自定义
__del__。此外,进行手动垃圾收集或重写所有内容以避免循环是一项巨大的工作。到那时,只需要修改 OrderedDict 就更容易了!
标签: python garbage-collection ordereddictionary