字典对象

type PyDictObject

PyObject 子类型表示 Python 字典对象。

PyTypeObject PyDict_Type
稳定 ABI 的一部分。

PyTypeObject 实例表示 Python 字典类型。这与 Python 层中的 dict 是同一个对象。

int PyDict_Check(PyObject *p)

如果 p 是一个 dict 对象或 dict 类型的子类型的实例,则返回 true。此函数始终成功。

int PyDict_CheckExact(PyObject *p)

如果 p 是一个 dict 对象,但不是 dict 类型的子类型的实例,则返回 true。此函数始终成功。

PyObject *PyDict_New()
返回值:新引用。稳定 ABI 的一部分。

返回一个新的空字典,或在失败时返回 NULL

PyObject *PyDictProxy_New(PyObject *mapping)
返回值:新引用。稳定 ABI 的一部分。

为一个强制只读行为的映射返回一个 types.MappingProxyType 对象。这通常用于创建视图以防止修改非动态类类型的字典。

void PyDict_Clear(PyObject *p)
稳定 ABI 的一部分。

清空现有字典中的所有键值对。

int PyDict_Contains
稳定 ABI 的一部分。

确定字典p是否包含key。如果p中的项与key匹配,则返回1,否则返回0。如果出错,则返回-1。这等同于 Python 表达式key in p

PyObject *PyDict_Copy(PyObject *p)
返回值:新引用。稳定 ABI 的一部分。

返回一个包含与p相同键值对的新字典。

int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val)
稳定 ABI 的一部分。

使用键keyval插入到字典p中。key必须可散列;如果不可散列,则会引发TypeError。成功时返回0,失败时返回-1。此函数不会窃取对val的引用。

int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val)
稳定 ABI 的一部分。

这与PyDict_SetItem()相同,但key指定为const char* UTF-8 编码的字节字符串,而不是PyObject*

int PyDict_DelItem(PyObject *p, PyObject *key)
稳定 ABI 的一部分。

删除字典p中键为key的条目。key必须可散列;如果不可散列,则会引发TypeError。如果key不在字典中,则会引发KeyError。成功时返回0,失败时返回-1

int PyDict_DelItemString(PyObject
稳定 ABI 的一部分。

这与 PyDict_DelItem() 相同,但key 被指定为 const char* UTF-8 编码的字节字符串,而不是 PyObject*

PyObject *PyDict_GetItem(PyObject *p, PyObject *key)
返回值:借用的引用。 稳定 ABI 的一部分。

从字典 p 中返回具有键 key 的对象。如果键 key 不存在,则返回 NULL,但设置异常。

注意

当此函数调用 __hash__()__eq__() 方法时发生的异常会被静默忽略。优先使用 PyDict_GetItemWithError() 函数。

3.10 版中已更改:出于历史原因,允许在不持有 GIL 的情况下调用此 API。现在不再允许这样做。

PyObject *PyDict_GetItemWithError(PyObject *p, PyObject *key)
返回值:借用的引用。 稳定 ABI 的一部分。

PyDict_GetItem() 的变体,它不抑制异常。如果发生异常,则连同设置的异常返回 NULL。如果键不存在,则设置异常返回 NULL

PyObject *PyDict_GetItemString(PyObject *p, const char *key)
返回值:借用的引用。 稳定 ABI 的一部分。

这与 PyDict_GetItem() 相同,但key 被指定为 const char* UTF-8 编码的字节字符串,而不是 PyObject*

注意

在调用 __hash__()__eq__() 方法或创建临时 str 对象时发生的异常将被忽略。最好使用 PyDict_GetItemWithError() 函数和您自己的 PyUnicode_FromString() key

PyObject *PyDict_SetDefault(PyObject *p, PyObject *key, PyObject *defaultobj)
返回值:借用引用。

这与 Python 级别的 dict.setdefault() 相同。如果存在,它将返回字典 p 中与 key 对应的值。如果字典中没有该键,则使用值 defaultobj 插入该键,并返回 defaultobj。此函数仅对 key 的哈希函数求值一次,而不是对查找和插入分别求值。

在 3.4 版本中添加。

PyObject *PyDict_Items(PyObject *p)
返回值:新引用。稳定 ABI 的一部分。

返回一个包含字典中所有项的 PyListObject

PyObject *PyDict_Keys(PyObject *p)
返回值:新引用。稳定 ABI 的一部分。

返回一个包含字典中所有键的 PyListObject

PyObject *PyDict_Values(PyObject *p)
返回值:新引用。稳定 ABI 的一部分。

返回一个包含字典 p 中所有值的 PyListObject

Py_ssize_t PyDict_Size(PyObject *p)
稳定 ABI 的一部分。

返回字典中的项数。这等同于字典上的 len(p)

int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
稳定 ABI 的一部分。

遍历字典 p 中的所有键值对。在首次调用此函数开始迭代之前,ppos 引用的 Py_ssize_t 必须初始化为 0;对于字典中的每一对,此函数返回 true,所有对都已报告后返回 false。参数 pkeypvalue 应指向 PyObject* 变量,分别用每个键和值填充,或者可以是 NULL。通过它们返回的任何引用都是借用的。在迭代过程中不应更改 ppos。它的值表示内部字典结构中的偏移量,并且由于结构是稀疏的,因此偏移量不是连续的。

例如

PyObject *key, *value;
Py_ssize_t pos = 0;

while (PyDict_Next(self->dict, &pos, &key, &value)) {
    /* do something interesting with the values... */
    ...
}

在迭代过程中不应改变字典 p。在遍历字典时修改键的值是安全的,但前提是键的集合不会改变。例如

PyObject *key, *value;
Py_ssize_t pos = 0;

while (PyDict_Next(self->dict, &pos, &key, &value)) {
    long i = PyLong_AsLong(value);
    if (i == -1 && PyErr_Occurred()) {
        return -1;
    }
    PyObject *o = PyLong_FromLong(i + 1);
    if (o == NULL)
        return -1;
    if (PyDict_SetItem(self->dict, key, o) < 0) {
        Py_DECREF(o);
        return -1;
    }
    Py_DECREF(o);
}
int PyDict_Merge(PyObject *a, PyObject *b, int override)
稳定 ABI 的一部分。

遍历映射对象 b,将键值对添加到字典 ab 可以是字典,或任何支持 PyMapping_Keys()PyObject_GetItem() 的对象。如果 override 为 true,则在 b 中找到匹配的键时,将替换 a 中的现有对,否则仅在 a 中没有匹配的键时才添加对。如果成功,返回 0,如果引发异常,则返回 -1

int PyDict_Update(PyObject *a, PyObject *b)
稳定 ABI 的一部分。

在 C 中,这与 PyDict_Merge(a, b, 1) 相同,在 Python 中类似于 a.update(b),不同之处在于,如果第二个参数没有“keys”属性,PyDict_Update() 不会回退到遍历键值对序列。如果成功,返回 0,如果引发异常,则返回 -1

int PyDict_MergeFromSeq2(PyObject *a, PyObject *seq2, int override)
稳定 ABI 的一部分。

seq2 中的键值对更新或合并到字典 a 中。seq2 必须是一个可迭代对象,生成长度为 2 的可迭代对象,视为键值对。对于重复键,如果 override 为 true,则最后一个获胜,否则第一个获胜。如果成功,则返回 0,如果引发异常,则返回 -1。等效的 Python(返回值除外)

def PyDict_MergeFromSeq2(a, seq2, override):
    for key, value in seq2:
        if override or key not in a:
            a[key] = value
int PyDict_AddWatcher(PyDict_WatchCallback callback)

callback 注册为字典观察者。返回一个非负整数 id,该 id 必须传递给对 PyDict_Watch() 的未来调用。如果出错(例如,没有更多观察者 ID 可用),则返回 -1 并设置异常。

在 3.12 版中添加。

int PyDict_ClearWatcher(int watcher_id)

清除先前从 PyDict_AddWatcher() 返回的 watcher_id 标识的观察者。如果成功,则返回 0,如果出错(例如,如果给定的 watcher_id 从未注册),则返回 -1

在 3.12 版中添加。

int PyDict_Watch(int watcher_id, PyObject *dict)

将字典 dict 标记为已观察。当修改或释放 dict 时,将调用 PyDict_AddWatcher() 授予 watcher_id 的回调。如果成功,则返回 0,如果出错,则返回 -1

在 3.12 版中添加。

int PyDict_Unwatch(int watcher_id, PyObject *dict)

将字典 dict 标记为不再观察。当修改或释放 dict 时,将不再调用 PyDict_AddWatcher() 授予 watcher_id 的回调。该字典之前必须已由该观察者观察。如果成功,则返回 0,如果出错,则返回 -1

在 3.12 版中添加。

类型 PyDict_WatchEvent

可能的字典观察器事件枚举:PyDict_EVENT_ADDEDPyDict_EVENT_MODIFIEDPyDict_EVENT_DELETEDPyDict_EVENT_CLONEDPyDict_EVENT_CLEAREDPyDict_EVENT_DEALLOCATED

在 3.12 版中添加。

typedef int (*PyDict_WatchCallback)(PyDict_WatchEvent event, PyObject *dict, PyObject *key, PyObject *new_value)

字典观察器回调函数的类型。

如果事件PyDict_EVENT_CLEAREDPyDict_EVENT_DEALLOCATED,则新值都将为 NULL。如果事件PyDict_EVENT_ADDEDPyDict_EVENT_MODIFIED,则新值将是的新值。如果事件PyDict_EVENT_DELETED,则将从字典中删除,新值将为 NULL

PyDict_EVENT_CLONED字典以前为空且另一个字典合并到其中时发生。为了保持此操作的效率,在这种情况下不会发出每个键的 PyDict_EVENT_ADDED 事件;而是发出一个 PyDict_EVENT_CLONED将是源字典。

回调可以检查但不得修改字典;这样做可能会产生不可预测的影响,包括无限递归。不要在回调中触发 Python 代码执行,因为它可能会作为副作用修改字典。

如果事件PyDict_EVENT_DEALLOCATED,则在回调中获取即将销毁的字典的新引用将使其复活并防止其此时被释放。当复活的对象稍后被销毁时,那时激活的任何观察器回调都将再次被调用。

回调在对字典进行通知的修改之前发生,因此可以检查字典的先前状态。

如果回调设置了一个异常,则它必须返回 -1;此异常将使用 PyErr_WriteUnraisable() 作为不可引发异常打印。否则它应该返回 0

进入回调时可能已经设置了一个挂起的异常。在这种情况下,回调应返回 0,同时仍设置相同的异常。这意味着回调可能不会调用任何其他可以设置异常的 API,除非它首先保存并清除异常状态,并在返回之前将其还原。

在 3.12 版中添加。