Является ли Python dict.pop атомарным?
Кажется разумным полагать, что dict.pop
работает атомарно, так как он поднимает KeyError
, если указанный ключ отсутствует, и по умолчанию предоставляется так:
d.pop(k)
Однако в документации не указано, что конкретно адресовано эта точка, по крайней мере, в разделе, специально не документирующем dict.pop
.
Этот вопрос возник у меня, когда я рассматривал мой ответ, который использовал этот шаблон:
if k in d: del d[k]
В то время я не думал о потенциальном условии, что ключ может присутствовать во время if
, но не во время del
. Если dict.pop
действительно предоставляет атомную альтернативу, я должен отметить это в своем ответе.
Ответы
Ответ 1
Для типа по умолчанию dict.pop()
- это вызов функции C, что означает, что он выполняется с одной оценкой байт-кода. Это делает этот вызов атомарным.
Нити Python переключаются только тогда, когда цикл оценки байт-кода позволяет им, поэтому на границах байт-кода. Некоторые функции Python C переходят в код Python (думаю, __dunder__
специальные крючки метода), но метод dict.pop()
не является, по крайней мере, не для типа dict
по умолчанию.
Ответ 2
Фактически dict.pop() не является атомарным. Например, если вы используете объект в качестве ключа dict, Python должен вызывать реализацию объекта __hash __(). Но вы можете использовать dict.popitem(), а это действительно атомно.