NpyString API#

版本 2.0 新增。

此 API 允許存取儲存在 NumPy StringDType 陣列中的 UTF-8 字串資料。請參閱 NEP-55 以取得關於 StringDType 設計的更深入細節。

範例#

載入字串#

假設我們正在為 StringDType 撰寫 ufunc 實作。如果我們取得指向 StringDType 陣列條目開頭的 const char *buf 指標,以及指向陣列描述器的 PyArray_Descr * 指標,則可以像這樣存取底層的字串資料

npy_string_allocator *allocator = NpyString_acquire_allocator(
        (PyArray_StringDTypeObject *)descr);

npy_static_string sdata = {0, NULL};
npy_packed_static_string *packed_string = (npy_packed_static_string *)buf;
int is_null = 0;

is_null = NpyString_load(allocator, packed_string, &sdata);

if (is_null == -1) {
    // failed to load string, set error
    return -1;
}
else if (is_null) {
    // handle missing string
    // sdata->buf is NULL
    // sdata->size is 0
}
else {
    // sdata->buf is a pointer to the beginning of a string
    // sdata->size is the size of the string
}
NpyString_release_allocator(allocator);

封裝字串#

此範例示範如何將新的字串條目封裝到陣列中

char *str = "Hello world";
size_t size = 11;
npy_packed_static_string *packed_string = (npy_packed_static_string *)buf;

npy_string_allocator *allocator = NpyString_acquire_allocator(
        (PyArray_StringDTypeObject *)descr);

// copy contents of str into packed_string
if (NpyString_pack(allocator, packed_string, str, size) == -1) {
    // string packing failed, set error
    return -1;
}

// packed_string contains a copy of "Hello world"

NpyString_release_allocator(allocator);

類型#

type npy_packed_static_string#

表示「封裝」編碼字串的不透明結構。陣列緩衝區中的個別條目是此結構的實例。直接存取結構中的資料是未定義的,且程式庫的未來版本可能會變更字串的封裝表示法。

type npy_static_string#

允許存取 UTF-8 字串資料的未封裝字串。

typedef struct npy_unpacked_static_string {
    size_t size;
    const char *buf;
} npy_static_string;
size_t size#

字串的大小,以位元組為單位。

const char *buf#

字串緩衝區。保存 UTF-8 編碼的位元組。目前不以空字串結尾,但我們可能會決定在未來新增空終止,因此請勿依賴空終止的存在與否。

請注意,這是一個 const 緩衝區。如果您想要變更陣列中的條目,您應該建立一個新的字串並將其封裝到陣列條目中。

type npy_string_allocator#

指向處理字串配置的物件的不透明指標。在使用配置器之前,您必須取得配置器鎖定,並在完成與配置器管理的字串互動後釋放鎖定。

type PyArray_StringDTypeObject#

在 Python 中支援 StringDType 實例的 C 結構。屬性儲存物件建立時的設定、npy_string_allocator 的實例 (管理與 DType 實例相關聯的陣列的字串配置),以及數個屬性 (快取在轉換和 ufunc 迴圈實作中常用的遺失字串物件的相關資訊)。

typedef struct {
    PyArray_Descr base;
    PyObject *na_object;
    char coerce;
    char has_nan_na;
    char has_string_na;
    char array_owned;
    npy_static_string default_string;
    npy_static_string na_name;
    npy_string_allocator *allocator;
} PyArray_StringDTypeObject;
PyArray_Descr base#

基礎物件。使用此成員來存取所有描述器物件共有的欄位。

PyObject *na_object#

參考代表空值的物件。如果沒有空值 (預設值),則這將會是 NULL。

char coerce#

如果啟用字串強制轉換,則為 1,否則為 0。

char has_nan_na#

如果遺失字串物件 (若有的話) 類似 NaN,則為 1,否則為 0。

char has_string_na#

如果遺失字串物件 (若有的話) 是字串,則為 1,否則為 0。

char array_owned#

如果陣列擁有 StringDType 實例,則為 1,否則為 0。

npy_static_string default_string#

在運算中使用的預設字串。如果遺失字串物件是字串,則這會包含遺失字串的字串資料。

npy_static_string na_name#

遺失字串物件的名稱 (若有的話)。否則為空字串。

npy_string_allocator allocator#

與擁有此描述器實例的陣列相關聯的配置器實例。只有在取得 allocator_lock 之後才能直接存取配置器,並且在不再需要配置器後應立即釋放鎖定

函數#

npy_string_allocator *NpyString_acquire_allocator(const PyArray_StringDTypeObject *descr)#

取得鎖定附加到 descr 的配置器的互斥鎖。NpyString_release_allocator 必須對此函數傳回的配置器呼叫正好一次。請注意,在持有配置器互斥鎖時,不應呼叫需要 GIL 的函數,因為這樣做可能會導致死鎖。

void NpyString_acquire_allocators(size_t n_descriptors, PyArray_Descr *const descrs[], npy_string_allocator *allocators[])#

同時取得鎖定附加到多個描述器的配置器的互斥鎖。針對陣列中每個 StringDType 描述器,在 allocators 陣列中寫入指向相關聯配置器的指標。如果任何描述器不是 StringDType 實例,則針對該條目在 allocators 陣列中寫入 NULL。

n_descriptors 是 descrs 陣列中應檢查的描述器數量。忽略 n_descriptors 元素之後的任何描述器。如果 descrs 陣列不包含 n_descriptors 元素,則會發生緩衝區溢位。

如果多次傳遞指向相同描述器的指標,則僅取得配置器互斥鎖一次,但會適當地設定相同的配置器指標。在此函數傳回後,必須釋放配置器互斥鎖,請參閱 NpyString_release_allocators

請注意,在持有配置器互斥鎖時,不應呼叫需要 GIL 的函數,因為這樣做可能會導致死鎖。

void NpyString_release_allocator(npy_string_allocator *allocator)#

釋放鎖定配置器的互斥鎖。在取得配置器互斥鎖且完成所有需要配置器的操作後,必須正好呼叫此函數一次。

如果您需要釋放多個配置器,請參閱 NpyString_release_allocators,其可以在給定多個相同配置器的參考時,正確地處理只釋放配置器一次。

void NpyString_release_allocators(size_t length, npy_string_allocator *allocators[])#

釋放鎖定 N 個配置器的互斥鎖。length 是 allocators 陣列的長度。忽略 NULL 條目。

如果多次傳遞指向相同配置器的指標,則只釋放配置器互斥鎖一次。

int NpyString_load(npy_string_allocator *allocator, const npy_packed_static_string *packed_string, npy_static_string *unpacked_string)#

packed_string 的封裝內容擷取到 unpacked_string 中。

unpacked_stringpacked_string 資料的唯讀檢視,不應用於修改字串資料。如果 packed_string 是空字串,則將 unpacked_string.buf 設定為 NULL 指標。如果解封裝字串失敗,則傳回 -1;如果 packed_string 是空字串,則傳回 1;否則傳回 0。

一個有用的模式是定義堆疊配置的 npy_static_string 實例,初始化為 {0, NULL},並將指向堆疊配置的未封裝字串的指標傳遞給此函數。此函數可用於同時解封裝字串並判斷其是否為空字串。

int NpyString_pack_null(npy_string_allocator *allocator, npy_packed_static_string *packed_string)#

將空字串封裝到 packed_string 中。成功時傳回 0,失敗時傳回 -1。

int NpyString_pack(npy_string_allocator *allocator, npy_packed_static_string *packed_string, const char *buf, size_t size)#

複製並封裝 buf 指向的緩衝區的前 size 個條目到 packed_string 中。成功時傳回 0,失敗時傳回 -1。