似乎有理由相信dict.pop
以原子方式运行,因为如果指定的键丢失并且没有提供默认值,它会引发KeyError
,如下所示:
d.pop(k)
但是,文档似乎没有专门针对这一点,至少在专门记录dict.pop
的部分中没有。
当我正在审核使用此模式的an answer of mine时,我发现了这个问题:
if k in d: del d[k]
当时,我没有想到if
期间可能存在密钥的潜在条件,而不是del
时的密钥。如果dict.pop
确实提供了原子替代方案,那么我应该在我的答案中注意到。
答案 0 :(得分:24)
对于默认类型,dict.pop()
是一个C函数调用,这意味着它是通过一个字节码评估执行的。这使得该调用成为原子。
Python线程仅在字节码评估循环允许时才切换,因此在字节码边界处。一些Python C函数会回调到Python代码(想想__dunder__
特殊方法钩子),但dict.pop()
方法不会,至少不是默认的dict
类型。
答案 1 :(得分:2)
实际上dict.pop()不是原子的。例如,如果你使用object作为dict的键,Python必须调用object的__hash __()实现。但你可以使用dict.popitem()代替真正的原子。