14

相信原子操作似乎是合理的,因为如果指定的键丢失并且没有提供默认值dict.pop,它会引发,如下所示:KeyError

d.pop(k)

但是,文档似乎没有具体解决这一点,至少在具体记录的部分中没有dict.pop

当我查看我使用这种模式的答案时,我想到了这个问题:

if k in d: del d[k]

当时,我没有想到在 期间可能存在密钥的潜在条件if,但在del. 如果dict.pop确实提供了原子替代方案,那么我应该在回答中指出这一点。

4

2 回答 2

31

对于默认类型,dict.pop()是一个 C 函数调用,这意味着它使用一个字节码评估来执行。这使得该调用具有原子性。

Python 线程仅在字节码评估循环允许它们时切换,因此在字节码边界处切换。一些 Python C 函数确实回调 Python 代码(想想__dunder__特殊的方法挂钩),但该dict.pop()方法没有,至少对于默认dict类型不是。

于 2013-06-26T16:55:37.303 回答
4

实际上 dict.pop() 不是原子的。例如,如果您使用 object 作为 dict 的键 Python 必须调用 object 的 __hash__() 实现。但是您可以使用真正原子的 dict.popitem() 代替。

于 2014-03-23T19:40:06.637 回答