Является ли 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(), а это действительно атомно.