字典物件

type PyDictObject

PyObject 的子型別表示 Python 字典物件。

PyTypeObject PyDict_Type
屬於 穩定 ABI 的一部分。

PyTypeObject 的例項表示 Python 字典型別。這與 Python 層中的 dict 物件相同。

int PyDict_Check(PyObject *p)

如果 p 是一個字典物件或字典型別的子型別的例項,則返回 true。此函式總是成功。

int PyDict_CheckExact(PyObject *p)

如果 p 是一個字典物件,但不是字典型別的子型別的例項,則返回 true。此函式總是成功。

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

返回一個新的空字典,失敗時返回 NULL

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

為對映返回一個 types.MappingProxyType 物件,該物件強制執行只讀行為。 這通常用於建立檢視,以防止修改非動態類型別的字典。

void PyDict_Clear(PyObject *p)
屬於 穩定 ABI 的一部分。

清空現有字典的所有鍵值對。

int PyDict_Contains(PyObject *p, PyObject *key)
屬於 穩定 ABI 的一部分。

確定字典 p 是否包含 key。 如果 p 中的某個專案與 key 匹配,則返回 1,否則返回 0。 發生錯誤時,返回 -1。 這等效於 Python 表示式 key in p

int PyDict_ContainsString(PyObject *p, const char *key)

這與 PyDict_Contains() 相同,但 key 被指定為 const char* UTF-8 編碼的位元組字串,而不是 PyObject*

在 3.13 版本中新增。

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

返回一個新字典,其中包含與 p 相同的鍵值對。

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

使用 key 作為鍵,將 val 插入到字典 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 *p, const char *key)
屬於 穩定 ABI 的一部分。

此函式與 PyDict_DelItem() 相同,但 key 被指定為 const char* UTF-8 編碼的位元組字串,而不是 PyObject*

int PyDict_GetItemRef(PyObject *p, PyObject *key, PyObject **result)
自 3.13 版本起成為 穩定 ABI 的一部分。

返回字典 p 中鍵為 key 的物件的新的 強引用

  • 如果鍵存在,則將 *result 設定為值的新的 強引用,並返回 1

  • 如果鍵不存在,則將 *result 設定為 NULL,並返回 0

  • 發生錯誤時,引發異常並返回 -1

在 3.13 版本中新增。

另請參閱 PyObject_GetItem() 函式。

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 來替代。

int PyDict_GetItemStringRef(PyObject *p, const char *key, PyObject **result)
自 3.13 版本起成為 穩定 ABI 的一部分。

PyDict_GetItemRef() 相似,但 key 被指定為 const char* UTF-8 編碼的位元組字串,而不是 PyObject*

在 3.13 版本中新增。

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

這與 Python 級別的 dict.setdefault() 相同。如果存在,它將返回字典 p 中與 key 對應的值。如果該鍵不在字典中,則會插入該鍵,其值為 defaultobj,並返回 defaultobj。此函式僅計算 key 的雜湊函式一次,而不是為查詢和插入分別獨立計算。

在 3.4 版本中新增。

int PyDict_SetDefaultRef(PyObject *p, PyObject *key, PyObject *default_value, PyObject **result)

如果鍵尚未存在於字典中,則將 default_value 插入到字典 p 中,鍵為 key。如果 result 不是 NULL,則 *result 將被設定為 default_value強引用(如果鍵不存在),或者設定為現有值(如果 key 已經存在於字典中)。如果鍵存在並且未插入 default_value,則返回 1;如果鍵不存在並且已插入 default_value,則返回 0。如果失敗,則返回 -1,設定一個異常,並將 *result 設定為 NULL

為了清楚起見:如果在呼叫此函式之前你擁有對 default_value 的強引用,則在函式返回後,你將同時擁有對 default_value*result 的強引用(如果它不是 NULL)。它們可能指向同一個物件:在這種情況下,你擁有對它的兩個單獨的引用。

在 3.13 版本中新增。

int PyDict_Pop(PyObject *p, PyObject *key, PyObject **result)

從字典 p 中刪除 key,並可以選擇返回已刪除的值。如果鍵不存在,則不引發 KeyError

  • 如果鍵存在,則在 result 不是 NULL 的情況下,將 *result 設定為對已刪除值的新引用,並返回 1

  • 如果鍵不存在,則在 result 不是 NULL 的情況下,將 *result 設定為 NULL,並返回 0

  • 發生錯誤時,引發異常並返回 -1

這類似於 dict.pop(),但沒有預設值,並且如果鍵不存在則不引發 KeyError

在 3.13 版本中新增。

int PyDict_PopString(PyObject *p, const char *key, PyObject **result)

類似於 PyDict_Pop(),但 key 被指定為 const char* UTF-8 編碼的位元組字串,而不是 PyObject*

在 3.13 版本中新增。

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

返回一個 PyListObject,其中包含字典中的所有項。

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

返回一個 PyListObject,其中包含字典中的所有鍵。

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

返回一個 PyListObject,其中包含字典 p 中的所有值。

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);
}

在沒有外部同步的自由執行緒構建中,此函式不是執行緒安全的。您可以使用Py_BEGIN_CRITICAL_SECTION來鎖定字典,同時遍歷它

Py_BEGIN_CRITICAL_SECTION(self->dict);
while (PyDict_Next(self->dict, &pos, &key, &value)) {
    ...
}
Py_END_CRITICAL_SECTION();
int PyDict_Merge(PyObject *a, PyObject *b, int override)
屬於 穩定 ABI 的一部分。

遍歷對映物件 b,將鍵值對新增到字典 a 中。b 可以是字典,或任何支援 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),只是 PyDict_Update() 不會回退到迭代鍵值對序列(如果第二個引數沒有“keys”屬性)。成功時返回 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 版本中新增。

type 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)

字典觀察者回調函式的型別。

如果 eventPyDict_EVENT_CLEAREDPyDict_EVENT_DEALLOCATED,則 keynew_value 都將為 NULL。如果 eventPyDict_EVENT_ADDEDPyDict_EVENT_MODIFIED,則 new_value 將是 key 的新值。如果 eventPyDict_EVENT_DELETED,則正在從字典中刪除 key,並且 new_value 將為 NULL

dict 之前為空並且另一個字典合併到其中時,會發生 PyDict_EVENT_CLONED。為了保持此操作的效率,在這種情況下不會發出每個鍵的 PyDict_EVENT_ADDED 事件;而是發出一個 PyDict_EVENT_CLONED,並且 key 將是源字典。

回撥可以檢查 dict,但不能修改它;這樣做可能會產生不可預測的影響,包括無限遞迴。請勿在回撥中觸發 Python 程式碼執行,因為它可能會作為副作用修改字典。

如果 eventPyDict_EVENT_DEALLOCATED,則在回撥中對即將銷燬的字典獲取新的引用會使其復活,並防止其此時被釋放。當復活的物件稍後被銷燬時,屆時處於活動狀態的任何觀察者回調都將再次被呼叫。

回調發生在對 dict 的已通知修改發生之前,因此可以檢查 dict 的先前狀態。

如果回撥函式設定了異常,它必須返回 -1;這個異常將使用 PyErr_WriteUnraisable() 作為不可引發的異常打印出來。否則,它應該返回 0

在進入回撥函式時,可能已經存在一個待處理的異常。在這種情況下,回撥函式應該返回 0,並且仍然設定相同的異常。這意味著回撥函式可能無法呼叫任何其他可能設定異常的 API,除非它首先儲存並清除異常狀態,並在返回之前恢復它。

在 3.12 版本中新增。