NpyString API#
2.0 版本新增。
此 API 允许访问存储在 NumPy StringDType 数组中的 UTF-8 字符串数据。有关 StringDType 设计的更多深入细节,请参见 NEP-55。
示例#
加载字符串#
假设我们正在为 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
缓冲区。如果您想修改数组中的条目,应创建一个新字符串并将其打包到数组条目中。
-
size_t size#
-
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#
基础对象。使用此成员访问所有描述符对象共有的字段。
-
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 后直接访问,并且在不再需要分配器后应立即释放该锁。
-
PyArray_Descr base#
函数#
-
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 描述符,将指向关联分配器的指针写入分配器数组。如果任何描述符不是 StringDType 实例,则将 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
是分配器数组的长度。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_string
是packed_string
数据的只读视图,不应用于修改字符串数据。如果packed_string
是空字符串,则将unpacked_string.buf
设置为 NULL 指针。如果解包字符串失败,返回 -1;如果packed_string
是空字符串,返回 1;否则返回 0。一个有用的模式是定义一个初始化为
{0, NULL}
的栈分配 npy_static_string 实例,并将指向该栈分配的解包字符串的指针传递给此函数。此函数可用于同时解包字符串并确定它是否为空字符串。
-
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。