weakref
模块的WeakKeyDictionary
和WeakValueDictionary
的文档中有一条关于迭代这些容器的注意事项:
作为这些容器行为规范的说明,这似乎相当可怕。特别是在运行使用 CPython 垃圾回收器(使用包含循环的数据结构)或使用另一个 Python 实现(例如 Jython)的代码时,听起来好像没有安全的方式可以迭代这些集合。Note: Caution: Because a WeakKeyDictionary is built on top of a Python dictionary, it must not change size when iterating over it. This can be difficult to ensure for a WeakKeyDictionary because actions performed by the program during iteration may cause items in the dictionary to vanish “by magic” (as a side effect of garbage collection).
当垃圾回收器可能在程序的任何时候清除引用时,我如何安全地迭代这些集合?我的首要解决方案是针对 CPython 的,但我也对其他实现中的问题感兴趣。
在 WeakKeyDictionary 上进行迭代的安全方法是什么?
import weakref
d = weakref.WeakKeyDictionary()
...
for k, v in list(d.items()):
...
__del__
方法,它无法与不释放GIL的C调用同时进行。这就是为什么大多数Python中的C调用都是原子的,如果它们不释放GIL,则没有其他Python代码可以与它们同时运行。” - Eloff