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#
与拥有此描述符实例的数组关联的分配器实例。应仅在获取分配器锁后直接访问分配器,并在不再需要分配器后立即释放该锁。
-
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 描述符的关联分配器的指针写入 allocators 数组。如果任何描述符不是 StringDType 实例,则为该条目在 allocators 数组中写入 NULL。
n_descriptors是 descrs 数组中应检查的描述符数量。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_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。