Содержание страницы
Буферные объекты¶Buffer Objects
Объекты Python, реализованные на C, могут экспортировать «буферный интерфейс». Эти функции могут использоваться объектом для предоставления своих данных в сыром, ориентированном на байты формате. Клиенты объекта могут использовать буферный интерфейс для прямого доступа к данным объекта без необходимости их предварительного копирования.
Два примера объектов, поддерживающих буферный интерфейс: bytes и arrays. Объект bytes предоставляет содержимое символов в байт-ориентированной форме буферного интерфейса. Массив также может предоставлять своё содержимое, однако следует отметить, что элементы массива могут быть многобайтовыми.
Примером использования буферного интерфейса является метод write() файлового объекта. Любой объект, который может экспортировать последовательность байтов через буферный интерфейс, может быть записан в файл. Существует ряд кодов формата для PyArg_ParseTuple, которые работают с буферным интерфейсом объекта, возвращая данные из целевого объекта.
Дополнительная информация о буферном интерфейсе приведена в разделе Структуры буферных объектов, в описании PyBufferProcs.
Буферные объекты полезны как способ предоставления данных из буферного интерфейса другого объекта программисту Python. Они также могут использоваться как механизм среза без копирования. Благодаря возможности ссылаться на блок памяти, можно довольно легко предоставить любые данные программисту Python. Память может быть большим постоянным массивом в расширении C, сырым блоком памяти для манипуляций перед передачей в библиотеку операционной системы или использоваться для передачи структурированных данных в их родном, внутрипамятном формате.
- Py_buffer¶
- void *buf¶
- Указатель на начало памяти объекта.
- Py_ssize_t len
- Общая длина памяти в байтах.
- int readonly¶
- Индикатор того, является ли буфер доступным только для чтения.
- const char *format
- Строка, завершающаяся нулём NULL, в синтаксисе стиля модуля struct, задающая содержимое элементов, доступных через буфер. Если это NULL, то предполагается "B" (беззнаковые байты).
- int ndim¶
- Количество измерений, которые память представляет как многомерный массив. Если оно равно 0, strides и suboffsets должны быть NULL.
- Py_ssize_t *shape¶
- Массив Py_ssize_t длиной ndim, задающий форму памяти как многомерного массива. Обратите внимание, что ((*shape)[0] * ... * (*shape)[ndims-1])*itemsize должно быть равно len.
- Py_ssize_t *strides¶
- Массив Py_ssize_t длиной ndim, задающий количество байтов, которое нужно пропустить, чтобы перейти к новому элементу в каждом измерении.
- Py_ssize_t *suboffsets¶
Массив Py_ssize_t длиной ndim. Если эти числа suboffset больше или равны 0, то значение, хранящееся по указанному измерению, является указателем, а значение suboffset определяет, сколько байтов добавить к указателю после разыменования. Отрицательное значение suboffset означает, что разыменование не должно выполняться (шаг в непрерывном блоке памяти).
Вот функция, которая возвращает указатель на элемент в N-мерном массиве, на который указывает N-мерный индекс, при наличии как ненулевых strides, так и suboffsets:
void *get_item_pointer(int ndim, void *buf, Py_ssize_t *strides, Py_ssize_t *suboffsets, Py_ssize_t *indices) { char *pointer = (char*)buf; int i; for (i = 0; i < ndim; i++) { pointer += strides[i] * indices[i]; if (suboffsets[i] >=0 ) { pointer = *((char**)pointer) + suboffsets[i]; } } return (void*)pointer; }
- Py_ssize_t itemsize¶
- Это хранилище для размера элемента (в байтах) каждого элемента разделяемой памяти. Технически оно необязательно, так как его можно получить с помощью PyBuffer_SizeFromFormat, однако экспортёр может знать эту информацию без разбора строки формата, и необходимо знать размер элемента для правильной интерпретации шагов (striding). Поэтому сохранение его более удобно и быстрее.
- void *internal¶
- Это поле предназначено для внутреннего использования экспортирующим объектом. Например, оно может быть переинтерпретировано как целое число экспортером и использоваться для хранения флагов о том, нужно ли освобождать массивы shape, strides и suboffsets при освобождении буфера. Потребитель никогда не должен изменять это значение.
Объекты MemoryView¶MemoryView objects
Объект memoryview – это расширенный буферный объект, который может заменить буферный объект (но не обязан, так как тот может оставаться простым одномерным объектом memoryview объект). Он, в отличие от Py_buffer, является объектом Python (предоставляется как memoryview в builtins), поэтому его можно использовать в коде Python.