dict.md
1> **Источник:** https://python-all.ru/3.12/c-api/dict.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Объекты словарей89#### `type PyDictObject`1011Этот подтип [`PyObject`](https://python-all.ru/3.12/c-api/structures.html#c.PyObject) представляет объект словаря Python.1213#### `PyTypeObject PyDict_Type`1415*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*1617Этот экземпляр [`PyTypeObject`](https://python-all.ru/3.12/c-api/type.html#c.PyTypeObject) представляет тип словаря Python. Это тот же объект, что и [`dict`](https://python-all.ru/3.12/library/stdtypes.html#dict) на уровне Python.1819#### `int PyDict_Check(PyObject *p)`2021Возвращает True, если *p* – объект dict или экземпляр подтипа типа dict. Эта функция всегда завершается успешно.2223#### `int PyDict_CheckExact(PyObject *p)`2425Возвращает True, если *p* – объект dict, но не экземпляр подтипа типа dict. Эта функция всегда завершается успешно.2627#### `PyObject *PyDict_New()`2829*Возвращаемое значение: новая ссылка.*3031*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*3233Возвращает новый пустой словарь или `NULL` в случае ошибки.3435#### `PyObject *PyDictProxy_New(PyObject *mapping)`3637*Возвращаемое значение: новая ссылка.*3839*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*4041Возвращает объект [`types.MappingProxyType`](https://python-all.ru/3.12/library/types.html#types.MappingProxyType) для отображения, которое принудительно обеспечивает режим только для чтения. Обычно используется для создания представления, предотвращающего изменение словаря для нединамических типов классов.4243#### `void PyDict_Clear(PyObject *p)`4445*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*4647Очищает существующий словарь от всех пар ключ-значение.4849#### `int PyDict_Contains(PyObject *p, PyObject *key)`5051*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*5253Определяет, содержит ли словарь *p* ключ *key*. Если элемент в *p* совпадает с *key*, возвращает `1`, иначе возвращает `0`. В случае ошибки возвращает `-1`. Это эквивалентно выражению Python `key in p`.5455#### `PyObject *PyDict_Copy(PyObject *p)`5657*Возвращаемое значение: новая ссылка.*5859*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*6061Возвращает новый словарь, содержащий те же пары ключ-значение, что и *p*.6263#### `int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val)`6465*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*6667Вставляет *val* в словарь *p* с ключом *key*. *key* должен быть [хешируемым](https://python-all.ru/3.12/glossary.html#term-hashable); в противном случае будет возбуждено [`TypeError`](https://python-all.ru/3.12/library/exceptions.html#TypeError). Возвращает `0` в случае успеха или `-1` при неудаче. Эта функция *не* похищает ссылку на *val*.6869#### `int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val)`7071*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*7273То же, что и [`PyDict_SetItem()`](https://python-all.ru/3.12/c-api/dict.html#c.PyDict_SetItem), но *key* задаётся как const char\* строка байтов в кодировке UTF-8, а не как [PyObject](https://python-all.ru/3.12/c-api/structures.html#c.PyObject)\*.7475#### `int PyDict_DelItem(PyObject *p, PyObject *key)`7677*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*7879Удаляет запись из словаря *p* с ключом *key*. *key* должен быть [хэшируемым](https://python-all.ru/3.12/glossary.html#term-hashable); если нет, возбуждается [`TypeError`](https://python-all.ru/3.12/library/exceptions.html#TypeError). Если *key* отсутствует в словаре, возбуждается [`KeyError`](https://python-all.ru/3.12/library/exceptions.html#KeyError). Возвращает `0` при успехе или `-1` при неудаче.8081#### `int PyDict_DelItemString(PyObject *p, const char *key)`8283*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*8485То же, что и [`PyDict_DelItem()`](https://python-all.ru/3.12/c-api/dict.html#c.PyDict_DelItem), но *key* задаётся как const char\* строка байтов в кодировке UTF-8, а не как [PyObject](https://python-all.ru/3.12/c-api/structures.html#c.PyObject)\*.8687#### `PyObject *PyDict_GetItem(PyObject *p, PyObject *key)`8889*Возвращаемое значение: заимствованная ссылка.*9091*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*9293Возвращает объект из словаря *p* по ключу *key*. Возвращает `NULL`, если ключ *key* отсутствует, но *без* установки исключения.9495> **Примечание**96>97> Исключения, возникающие при вызове методов [`__hash__()`](https://python-all.ru/3.12/reference/datamodel.html#object.__hash__) и [`__eq__()`](https://python-all.ru/3.12/reference/datamodel.html#object.__eq__), молча игнорируются. Вместо этого рекомендуется использовать функцию [`PyDict_GetItemWithError()`](https://python-all.ru/3.12/c-api/dict.html#c.PyDict_GetItemWithError).9899Изменено в версии 3.10: Вызов этого API без удержания [GIL](https://python-all.ru/3.12/glossary.html#term-GIL) ранее допускался по историческим причинам. Теперь это не допускается.100101#### `PyObject *PyDict_GetItemWithError(PyObject *p, PyObject *key)`102103*Возвращаемое значение: заимствованная ссылка.*104105*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*106107Вариант [`PyDict_GetItem()`](https://python-all.ru/3.12/c-api/dict.html#c.PyDict_GetItem), который не подавляет исключения. Возвращает `NULL` **с** установленным исключением, если произошло исключение. Возвращает `NULL` **без** установленного исключения, если ключ отсутствовал.108109#### `PyObject *PyDict_GetItemString(PyObject *p, const char *key)`110111*Возвращаемое значение: заимствованная ссылка.*112113*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*114115Это то же самое, что и [`PyDict_GetItem()`](https://python-all.ru/3.12/c-api/dict.html#c.PyDict_GetItem), но *key* задается как const char\* строка байтов в кодировке UTF-8, а не [PyObject](https://python-all.ru/3.12/c-api/structures.html#c.PyObject)\*.116117> **Примечание**118>119> Исключения, возникающие при вызове методов [`__hash__()`](https://python-all.ru/3.12/reference/datamodel.html#object.__hash__) и [`__eq__()`](https://python-all.ru/3.12/reference/datamodel.html#object.__eq__) или при создании временного объекта [`str`](https://python-all.ru/3.12/library/stdtypes.html#str), молча игнорируются. Вместо этого рекомендуется использовать функцию [`PyDict_GetItemWithError()`](https://python-all.ru/3.12/c-api/dict.html#c.PyDict_GetItemWithError) с собственным [`PyUnicode_FromString()`](https://python-all.ru/3.12/c-api/unicode.html#c.PyUnicode_FromString) *key*.120121#### `PyObject *PyDict_SetDefault(PyObject *p, PyObject *key, PyObject *defaultobj)`122123*Возвращаемое значение: заимствованная ссылка.*124125Это то же самое, что и функция [`dict.setdefault()`](https://python-all.ru/3.12/library/stdtypes.html#dict.setdefault) на уровне Python. Если значение присутствует, она возвращает значение, соответствующее *key*, из словаря *p*. Если ключ отсутствует в словаре, он вставляется со значением *defaultobj* и возвращается *defaultobj*. Эта функция вычисляет хеш-функцию для *key* только один раз, вместо того чтобы вычислять её отдельно для поиска и вставки.126127Добавлено в версии 3.4.128129#### `PyObject *PyDict_Items(PyObject *p)`130131*Возвращаемое значение: новая ссылка.*132133*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*134135Возвращает [`PyListObject`](https://python-all.ru/3.12/c-api/list.html#c.PyListObject), содержащий все элементы из словаря.136137#### `PyObject *PyDict_Keys(PyObject *p)`138139*Возвращаемое значение: новая ссылка.*140141*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*142143Возвращает [`PyListObject`](https://python-all.ru/3.12/c-api/list.html#c.PyListObject), содержащий все ключи из словаря.144145#### `PyObject *PyDict_Values(PyObject *p)`146147*Возвращаемое значение: новая ссылка.*148149*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*150151Возвращает [`PyListObject`](https://python-all.ru/3.12/c-api/list.html#c.PyListObject), содержащий все значения из словаря *p*.152153#### `Py_ssize_t PyDict_Size(PyObject *p)`154155*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*156157Возвращает количество элементов в словаре. Это эквивалентно вызову `len(p)` для словаря.158159#### `int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)`160161*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*162163Перебирает все пары ключ-значение в словаре *p*. Значение [`Py_ssize_t`](https://python-all.ru/3.12/c-api/intro.html#c.Py_ssize_t), на которое указывает *ppos*, должно быть инициализировано `0` перед первым вызовом этой функции для начала итерации; функция возвращает true для каждой пары в словаре и false, когда все пары сообщены. Параметры *pkey* и *pvalue* должны либо указывать на переменные типа [PyObject](https://python-all.ru/3.12/c-api/structures.html#c.PyObject)\*, которые будут заполнены соответствующими ключом и значением, либо могут быть `NULL`. Все ссылки, возвращаемые через них, являются заимствованными. *ppos* не должен изменяться во время итерации. Его значение представляет смещения внутри внутренней структуры словаря, и поскольку структура разреженная, смещения не являются последовательными.164165Например:166167```c168PyObject *key, *value;169Py_ssize_t pos = 0;170171while (PyDict_Next(self->dict, &pos, &key, &value)) {172 /* сделайте что-нибудь интересное со значениями... */173 ...174}175```176177Словарь *p* не должен изменяться во время итерации. Можно безопасно изменять значения ключей при переборе словаря, но только до тех пор, пока набор ключей не меняется. Например:178179```c180PyObject *key, *value;181Py_ssize_t pos = 0;182183while (PyDict_Next(self->dict, &pos, &key, &value)) {184 long i = PyLong_AsLong(value);185 if (i == -1 && PyErr_Occurred()) {186 return -1;187 }188 PyObject *o = PyLong_FromLong(i + 1);189 if (o == NULL)190 return -1;191 if (PyDict_SetItem(self->dict, key, o) < 0) {192 Py_DECREF(o);193 return -1;194 }195 Py_DECREF(o);196}197```198199#### `int PyDict_Merge(PyObject *a, PyObject *b, int override)`200201*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*202203Перебирает объект отображения *b*, добавляя пары ключ-значение в словарь *a*. *b* может быть словарем или любым объектом, поддерживающим [`PyMapping_Keys()`](https://python-all.ru/3.12/c-api/mapping.html#c.PyMapping_Keys) и [`PyObject_GetItem()`](https://python-all.ru/3.12/c-api/object.html#c.PyObject_GetItem). Если *override* равно true, существующие пары в *a* будут заменены, если найден совпадающий ключ в *b*; в противном случае пары будут добавлены только если нет совпадающего ключа в *a*. Возвращает `0` при успехе или `-1`, если было возбуждено исключение.204205#### `int PyDict_Update(PyObject *a, PyObject *b)`206207*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*208209То же самое, что и `PyDict_Merge(a, b, 1)` в C, и похоже на `a.update(b)` в Python, за исключением того, что [`PyDict_Update()`](https://python-all.ru/3.12/c-api/dict.html#c.PyDict_Update) не переходит к итерации по последовательности пар ключ-значение, если у второго аргумента нет атрибута “keys”. Возвращает `0` при успехе или `-1`, если было возбуждено исключение.210211#### `int PyDict_MergeFromSeq2(PyObject *a, PyObject *seq2, int override)`212213*Часть [Stable ABI](https://python-all.ru/3.12/c-api/stable.html#stable).*214215Обновляет или объединяет словарь *a*, используя пары ключ-значение из *seq2*. *seq2* должен быть итерируемым объектом, который возвращает итерируемые объекты длины 2, рассматриваемые как пары ключ-значение. При повторяющихся ключах последнее значение побеждает, если *override* истинно, иначе первое. Возвращает `0` при успехе или `-1`, если возникло исключение. Эквивалент на Python (за исключением возвращаемого значения):216217```c218def PyDict_MergeFromSeq2(a, seq2, override):219 for key, value in seq2:220 if override or key not in a:221 a[key] = value222```223224#### `int PyDict_AddWatcher(PyDict_WatchCallback callback)`225226Регистрирует *колбэк* в качестве наблюдателя словаря. Возвращает неотрицательное целое id, которое должно передаваться в последующие вызовы [`PyDict_Watch()`](https://python-all.ru/3.12/c-api/dict.html#c.PyDict_Watch). В случае ошибки (например, закончились идентификаторы наблюдателей) возвращает `-1` и устанавливает исключение.227228Добавлено в версии 3.12.229230#### `int PyDict_ClearWatcher(int watcher_id)`231232Удаляет наблюдателя, идентифицированного *watcher\_id*, ранее возвращённого из [`PyDict_AddWatcher()`](https://python-all.ru/3.12/c-api/dict.html#c.PyDict_AddWatcher). Возвращает `0` при успехе, `-1` при ошибке (например, если указанный *watcher\_id* никогда не был зарегистрирован).233234Добавлено в версии 3.12.235236#### `int PyDict_Watch(int watcher_id, PyObject *dict)`237238Помечает словарь *dict* как наблюдаемый. Колбэк, которому *watcher\_id* был назначен [`PyDict_AddWatcher()`](https://python-all.ru/3.12/c-api/dict.html#c.PyDict_AddWatcher), будет вызываться при изменении или освобождении *dict*. Возвращает `0` при успехе или `-1` при ошибке.239240Добавлено в версии 3.12.241242#### `int PyDict_Unwatch(int watcher_id, PyObject *dict)`243244Помечает словарь *dict* как больше не наблюдаемый. Колбэк, которому *watcher\_id* был назначен [`PyDict_AddWatcher()`](https://python-all.ru/3.12/c-api/dict.html#c.PyDict_AddWatcher), больше не будет вызываться при изменении или освобождении *dict*. Словарь ранее должен был быть наблюдаемым этим наблюдателем. Возвращает `0` при успехе или `-1` при ошибке.245246Добавлено в версии 3.12.247248#### `type PyDict_WatchEvent`249250Перечисление возможных событий наблюдателя словаря: `PyDict_EVENT_ADDED`, `PyDict_EVENT_MODIFIED`, `PyDict_EVENT_DELETED`, `PyDict_EVENT_CLONED`, `PyDict_EVENT_CLEARED`, или `PyDict_EVENT_DEALLOCATED`.251252Добавлено в версии 3.12.253254#### `typedef int (*PyDict_WatchCallback)(PyDict_WatchEvent event, PyObject *dict, PyObject *key, PyObject *new_value)`255256Тип функции колбэка наблюдателя словаря.257258Если *event* равен `PyDict_EVENT_CLEARED` или `PyDict_EVENT_DEALLOCATED`, то и *key*, и *new\_value* будут равны `NULL`. Если *event* равен `PyDict_EVENT_ADDED` или `PyDict_EVENT_MODIFIED`, *new\_value* будет новым значением для *key*. Если *event* равен `PyDict_EVENT_DELETED`, *key* удаляется из словаря, и *new\_value* будет равен `NULL`.259260`PyDict_EVENT_CLONED` происходит, когда *dict* ранее был пуст, и в него объединяется другой словарь. Для сохранения эффективности этой операции события `PyDict_EVENT_ADDED` для каждого ключа в этом случае не выдаются; вместо этого выдаётся одно `PyDict_EVENT_CLONED`, и *key* будет исходным словарём.261262Колбэк может проверять, но не должен изменять *dict*; это может привести к непредсказуемым последствиям, включая бесконечную рекурсию. Не запускайте выполнение кода Python в колбэке, так как это может изменить словарь в качестве побочного эффекта.263264Если *event* равен `PyDict_EVENT_DEALLOCATED`, получение новой ссылки в колбэке на словарь, который будет уничтожен, воскресит его и предотвратит его освобождение в этот момент. Когда воскрешённый объект будет уничтожен позже, все активные на тот момент колбэки наблюдателей будут вызваны снова.265266Колбэки происходят до того, как происходит уведомляемое изменение *dict*, поэтому можно проверить предыдущее состояние *dict*.267268Если обратный вызов устанавливает исключение, он должен вернуть `-1`; это исключение будет выведено как неподнимаемое исключение с помощью [`PyErr_WriteUnraisable()`](https://python-all.ru/3.12/c-api/exceptions.html#c.PyErr_WriteUnraisable). В противном случае он должен вернуть `0`.269270На момент входа в обратный вызов уже может быть установлено отложенное исключение. В этом случае обратный вызов должен вернуть `0`, оставив то же исключение установленным. Это означает, что обратный вызов не может вызывать никакой другой API, который может установить исключение, если только он сначала не сохранит и не очистит состояние исключения, а затем не восстановит его перед возвратом.271272Добавлено в версии 3.12.273