2013-06-26 48 views
9

似乎有理由相信,dict.pop原子操作,因爲它提出了KeyError如果指定鍵是失蹤,沒有默認設置,像這樣:是Python的dict.pop原子嗎?

d.pop(k) 

但是,文件沒有出現專門針對這一點,至少不在具體記載dict.pop的部分。

這個問題發生在我身上,因爲我正在審查an answer of mine其使用該模式:if期間

if k in d: del d[k] 

當時,我沒有想到的潛在條件,一個關鍵的可能是存在的,但不在del時。如果dict.pop確實提供了原子替代方法,那麼我應該在我的答案中注意。

+2

相關:[什麼樣的全局值突變是線程安全的?](http://goo.gl/dHxwN) –

回答

21

對於默認類型,dict.pop()是一個C函數調用,這意味着它將以執行一個字節碼評估。這使得這個調用是原子的。

只有當字節碼評估循環允許它們時,Python線程纔會切換,所以在字節碼邊界處。一些Python C函數確實會回調Python代碼(認爲__dunder__特殊方法鉤子),但dict.pop()方法不會,至少不適用於默認的dict類型。

+0

很好的解釋... –

+0

高於我的paygrade解釋明智的方式。只有一個問題:任何人都瞭解Jython的情況? –

+0

查看[Jython Concurrency文檔](http://www.jython.org/jythonbook/en/1.0/Concurrency.html):* Jython通過使用Java的ConcurrentHashMap實現dict和set。這意味着你可以使用這些標準的Python類型,並且仍然可以獲得高性能的併發性。 (它們也像CPython中的原子一樣,如我們將要描述的那樣)。* –

2

其實dict.pop()不是原子的。例如,如果你使用object作爲字典的鍵,Python必須調用object的__hash __()實現。但是你可以使用dict.popitem(),而不是真正的原子。

+1

您的答案從根本上與最受歡迎的答案相矛盾。你仍然相信你是對的嗎?如果是這樣,爲什麼?否則,你能否提出一個免責聲明或某事使得像我這樣的人不會感到困惑? –

+0

不是根本性的。 @ martijn-pieters講述了標準類型(實際上是基本類型)。但是,通常不希望dict.pop()總是原子的。 – renskiy

+0

當你說_「如果你使用對象作爲字典的鍵」_,你是什麼意思的對象?我認爲Python中的所有內容都是一個? –