NpyString API#
Добавлено в версии 2.0.
Этот API предоставляет доступ к строковым данным UTF-8, хранящимся в массивах NumPy StringDType. См. NEP-55 для более подробной информации о дизайне StringDType.
Примеры#
Загрузка строки#
Допустим, мы пишем реализацию ufunc для StringDType. Если нам дано
const char *buf указатель на начало StringDType элемент массива, и
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);
Типы#
-
тип npy_packed_static_string#
Непрозрачная структура, представляющая "упакованные" закодированные строки. Отдельные записи в буферах массивов являются экземплярами этой структуры. Прямой доступ к данным в структуре не определен, и будущие версии библиотеки могут изменить упакованное представление строк.
-
тип npy_static_string#
Распакованная строка, позволяющая получить доступ к данным строки UTF-8.
typedef struct npy_unpacked_static_string { size_t size; const char *buf; } npy_static_string;
-
size_t размер#
Размер строки в байтах.
-
const char *buf#
Строковый буфер. Содержит байты в кодировке UTF-8. В настоящее время не заканчивается нулевой строкой, но мы можем решить добавить нулевое завершение в будущем, поэтому не полагайтесь на наличие или отсутствие нулевого завершения.
Обратите внимание, что это
constбуфер. Если вы хотите изменить запись в массиве, вам следует создать новую строку и упаковать её в запись массива.
-
size_t размер#
-
тип npy_string_allocator#
Непрозрачный указатель на объект, который управляет выделением памяти для строк. Перед использованием аллокатора необходимо получить блокировку аллокатора и освободить блокировку после завершения работы со строками, управляемыми аллокатором.
-
тип PyArray_StringDTypeObject#
Структура C, поддерживающая экземпляры StringDType в Python. Атрибуты хранят настройки, с которыми был создан объект, экземпляр
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 основание#
Базовый объект. Используйте этот член для доступа к полям, общим для всех объектов-дескрипторов.
-
PyObject *na_object#
Ссылка на объект, представляющий нулевое значение. Если нулевого значения нет (по умолчанию), это будет NULL.
-
char coerce#
1, если приведение строк включено, 0 в противном случае.
-
char has_nan_na#
1, если отсутствующий строковый объект (если есть) похож на NaN, 0 в противном случае.
-
char has_string_na#
1, если отсутствующий строковый объект (если есть) является строкой, 0 в противном случае.
-
char array_owned#
1, если массив владеет экземпляром StringDType, 0 в противном случае.
-
npy_static_string default_string#
Строка по умолчанию для использования в операциях. Если объект пропущенной строки является строкой, это будет содержать строковые данные для пропущенной строки.
-
npy_static_string na_name#
Имя отсутствующего строкового объекта, если есть. Пустая строка в противном случае.
-
npy_string_allocator аллокатор#
Экземпляр аллокатора, связанный с массивом, которому принадлежит этот экземпляр дескриптора. К аллокатору следует обращаться напрямую только после получения блокировки allocator_lock, и блокировка должна быть снята сразу после того, как аллокатор больше не нужен
-
PyArray_Descr основание#
Функции#
-
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 *аллокаторы[])#
Одновременно захватить мьютексы, блокирующие аллокаторы, прикрепленные к нескольким дескрипторам. Записывает указатель на связанный аллокатор в массив аллокаторов для каждого дескриптора StringDType в массиве. Если любой из дескрипторов не является экземпляром StringDType, записывает NULL в массив аллокаторов для этой записи.
n_descriptorsэто количество дескрипторов в массиве descrs, которые должны быть проверены. Любой дескриптор послеn_descriptorsэлементы игнорируются. Произойдет переполнение буфера, еслиdescrsмассив не содержит n_descriptors элементов.Если указатели на один и тот же дескриптор передаются несколько раз, мьютекс аллокатора захватывается только один раз, но идентичные указатели аллокатора устанавливаются соответствующим образом. Мьютексы аллокатора должны быть освобождены после возврата из этой функции, см.
NpyString_release_allocators.Обратите внимание, что функции, требующие GIL, не должны вызываться, пока удерживается мьютекс аллокатора, так как это может привести к взаимным блокировкам.
-
void NpyString_release_allocator(npy_string_allocator *аллокатор)#
Освободить мьютекс, блокирующий аллокатор. Это должно быть вызвано ровно один раз после получения мьютекса аллокатора и завершения всех операций, требующих аллокатор.
Если необходимо освободить несколько аллокаторов, см. NpyString_release_allocators, который может корректно обрабатывать освобождение аллокатора один раз при наличии нескольких ссылок на тот же аллокатор.
-
void NpyString_release_allocators(size_t длина, npy_string_allocator *аллокаторы[])#
Освободить мьютексы, блокирующие N аллокаторов.
lengthэто длина массива аллокаторов. NULL-записи игнорируются.Если указатели на один и тот же аллокатор передаются несколько раз, освобождает мьютекс аллокатора только один раз.
-
int NpyString_load(npy_string_allocator *аллокатор, const npy_packed_static_string *packed_string, npy_static_string *unpacked_string)#
Извлечь упакованное содержимое
packed_stringвunpacked_string.The
unpacked_stringявляется представлением только для чтения наpacked_stringданные и не должен использоваться для изменения строковых данных. Еслиpacked_stringявляется пустой строкой, устанавливаетunpacked_string.bufв NULL указатель. Возвращает -1, если распаковка строки не удалась, возвращает 1, еслиpacked_stringявляется пустой строкой, и возвращает 0 в противном случае.Полезный шаблон — определить статически размещенный экземпляр npy_static_string, инициализированный как
{0, NULL}и передать указатель на размещенную в стеке распакованную строку этой функции. Эта функция может использоваться для одновременной распаковки строки и определения, является ли она нулевой строкой.
-
int NpyString_pack_null(npy_string_allocator *аллокатор, npy_packed_static_string *packed_string)#
Упаковать пустую строку в
packed_string. Возвращает 0 при успехе и -1 при неудаче.
-
int NpyString_pack(npy_string_allocator *аллокатор, npy_packed_static_string *packed_string, const char *buf, size_t размер)#
Копировать и упаковать первые
sizeэлементы буфера, на который указываетbufвpacked_string. Возвращает 0 при успехе и -1 при неудаче.