Документация Python неофициальный перевод

buffer.md

282 строк · 32.5 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.4/c-api/buffer.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Протокол буфера89Некоторые объекты в Python предоставляют доступ к лежащему в основе массиву памяти или *буферу*. К таким объектам относятся встроенные [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes) и [`bytearray`](https://python-all.ru/3.4/library/functions.html#bytearray), а также некоторые типы расширений, например [`array.array`](https://python-all.ru/3.4/library/array.html#array.array). Сторонние библиотеки могут определять собственные типы для специальных целей, таких как обработка изображений или численный анализ.1011Хотя каждый из этих типов имеет свою семантику, их объединяет общая характеристика: все они основаны на возможно большом буфере памяти. В некоторых ситуациях желательно получить прямой доступ к этому буферу без промежуточного копирования.1213Python предоставляет такую возможность на уровне C в виде [*буферного протокола*](https://python-all.ru/3.4/c-api/buffer.html#bufferobjects). У этого протокола есть две стороны:1415- На стороне производителя тип может экспортировать «буферный интерфейс», который позволяет объектам этого типа предоставлять информацию о своём базовом буфере. Этот интерфейс описан в разделе [*Buffer Object Structures*](https://python-all.ru/3.4/c-api/typeobj.html#buffer-structs);16- На стороне потребителя доступно несколько способов получить указатель на необработанные базовые данные объекта (например, параметр метода).1718Простые объекты, такие как [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes) и [`bytearray`](https://python-all.ru/3.4/library/functions.html#bytearray), предоставляют свой базовый буфер в байт-ориентированной форме. Возможны и другие формы; например, элементы, предоставляемые [`array.array`](https://python-all.ru/3.4/library/array.html#array.array), могут быть многобайтовыми значениями.1920Примером потребителя интерфейса буфера является метод [`write()`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase.write) файловых объектов: любой объект, способный экспортировать последовательность байтов через интерфейс буфера, может быть записан в файл. В то время как `write()` требует только доступа на чтение к внутреннему содержимому переданного ему объекта, другие методы, такие как [`readinto()`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase.readinto), требуют доступа на запись к содержимому своего аргумента. Интерфейс буфера позволяет объектам выборочно разрешать или запрещать экспорт буферов для чтения-записи и только для чтения.2122Существует два способа для потребителя буферного интерфейса получить буфер над целевым объектом:2324- вызов [`PyObject_GetBuffer()`](https://python-all.ru/3.4/c-api/buffer.html#c.PyObject_GetBuffer) с правильными параметрами;25- вызов [`PyArg_ParseTuple()`](https://python-all.ru/3.4/c-api/arg.html#c.PyArg_ParseTuple) (или одной из его разновидностей) с одним из `y*`, `w*` или `s*` [*кодов формата*](https://python-all.ru/3.4/c-api/arg.html#arg-parsing).2627В обоих случаях [`PyBuffer_Release()`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBuffer_Release) необходимо вызвать, когда буфер больше не нужен. Несоблюдение этого может привести к различным проблемам, таким как утечка ресурсов.2829## Структура буфера3031Структуры буферов (или просто «буферы») полезны как способ предоставления бинарных данных из другого объекта программисту на Python. Их также можно использовать как механизм среза с нулевым копированием. Благодаря возможности ссылаться на блок памяти, можно довольно легко предоставить любые данные программисту на Python. Память может быть большим константным массивом в C-расширении, необработанным блоком памяти для манипуляций перед передачей в библиотеку операционной системы или использоваться для передачи структурированных данных в их родном формате в памяти.3233В отличие от большинства типов данных, предоставляемых интерпретатором Python, буферы не являются указателями на [`PyObject`](https://python-all.ru/3.4/c-api/structures.html#c.PyObject), а представляют собой простые структуры C. Это позволяет создавать и копировать их очень просто. Когда требуется универсальная обёртка вокруг буфера, можно создать объект [*memoryview*](https://python-all.ru/3.4/c-api/memoryview.html#memoryview-objects).3435Краткие инструкции по написанию экспортирующего объекта см. в разделе [*Структуры объектов буфера*](https://python-all.ru/3.4/c-api/typeobj.html#buffer-structs). Для получения буфера см. [`PyObject_GetBuffer()`](https://python-all.ru/3.4/c-api/buffer.html#c.PyObject_GetBuffer).3637**`Py_buffer`**3839**void \*`buf`**4041Указатель на начало логической структуры, описываемой полями буфера. Это может быть любое место в базовом физическом блоке памяти экспортёра. Например, при отрицательных [`шагах`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.strides) значение может указывать на конец блока памяти.4243Для непрерывных массивов значение указывает на начало блока памяти.4445**void \*`obj`**4647Новая ссылка на экспортирующий объект. Ссылка принадлежит потребителю и автоматически уменьшается на единицу и устанавливается в *NULL* функцией [`PyBuffer_Release()`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBuffer_Release). Это поле эквивалентно возвращаемому значению любой стандартной функции C-API.4849В особом случае для *временных* буферов, которые обёрнуты функциями [`PyMemoryView_FromBuffer()`](https://python-all.ru/3.4/c-api/memoryview.html#c.PyMemoryView_FromBuffer) или [`PyBuffer_FillInfo()`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBuffer_FillInfo), это поле равно *NULL*. В общем случае экспортирующие объекты НЕ ДОЛЖНЫ использовать эту схему.5051**Py\_ssize\_t `len`**5253`product(shape) * itemsize`. Для непрерывных массивов это длина базового блока памяти. Для несплошных массивов это длина, которую имела бы логическая структура, если бы она была скопирована в непрерывное представление.5455Доступ к `((char *)buf)[0] до ((char *)buf)[len-1]` действителен только в том случае, если буфер был получен с помощью запроса, гарантирующего непрерывность. В большинстве случаев такой запрос будет [`PyBUF_SIMPLE`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBUF_SIMPLE) или [`PyBUF_WRITABLE`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBUF_WRITABLE).5657**int `readonly`**5859Индикатор того, является ли буфер доступным только для чтения. Это поле управляется флагом [`PyBUF_WRITABLE`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBUF_WRITABLE).6061**Py\_ssize\_t `itemsize`**6263Размер одного элемента в байтах. То же, что значение [`struct.calcsize()`](https://python-all.ru/3.4/library/struct.html#struct.calcsize), вызванной для значений [`format`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.format), не равных NULL.6465Важное исключение: если потребитель запрашивает буфер без флага [`PyBUF_FORMAT`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBUF_FORMAT), [`format`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.format) будет установлен в *NULL*, но [`itemsize`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.itemsize) по-прежнему содержит значение исходного формата.6667Если [`shape`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.shape) присутствует, равенство `product(shape) * itemsize == len` по-прежнему выполняется, и потребитель может использовать [`itemsize`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.itemsize) для навигации по буферу.6869Если [`shape`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.shape) равен *NULL* в результате запроса [`PyBUF_SIMPLE`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBUF_SIMPLE) или [`PyBUF_WRITABLE`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBUF_WRITABLE), потребитель должен игнорировать [`itemsize`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.itemsize) и считать `itemsize == 1`.7071**const char \*`format`**7273Строка, завершающаяся *NUL*, в синтаксисе стиля модуля [`struct`](https://python-all.ru/3.4/library/struct.html#module-struct), описывающая содержимое одного элемента. Если это *NULL*, предполагается `"B"` (беззнаковые байты).7475Это поле управляется флагом [`PyBUF_FORMAT`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBUF_FORMAT).7677**int `ndim`**7879Количество измерений, которое память представляет в виде n-мерного массива. Если оно равно 0, [`buf`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.buf) указывает на единственный элемент, представляющий скаляр. В этом случае [`shape`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.shape), [`strides`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.strides) и [`suboffsets`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.suboffsets) ДОЛЖНЫ быть *NULL*.8081Макрос `PyBUF_MAX_NDIM` ограничивает максимальное количество измерений до 64. Экспортёры ДОЛЖНЫ соблюдать это ограничение, потребители многомерных буферов должны быть способны обрабатывать до `PyBUF_MAX_NDIM` измерений.8283**Py\_ssize\_t \*`shape`**8485Массив из `Py_ssize_t` длиной [`ndim`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.ndim), описывающий форму памяти как n-мерный массив. Обратите внимание, что `shape[0] * ... * shape[ndim-1] * itemsize` ДОЛЖНО быть равно [`len`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.len).8687Значения shape ограничены `shape[n] >= 0`. Случай `shape[n] == 0` требует особого внимания. См. [complex arrays](https://python-all.ru/3.4/c-api/buffer.html#complex-arrays) для получения дополнительной информации.8889Массив формы доступен потребителю только для чтения.9091**Py\_ssize\_t \*`strides`**9293Массив из `Py_ssize_t` длиной [`ndim`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.ndim), указывающий количество байтов, которое необходимо пропустить, чтобы перейти к новому элементу в каждом измерении.9495Значения шага могут быть любым целым числом. Для обычных массивов шаги обычно положительны, но потребитель ДОЛЖЕН уметь обрабатывать случай `strides[n] <= 0`. См. [сложные массивы](https://python-all.ru/3.4/c-api/buffer.html#complex-arrays) для получения дополнительной информации.9697Массив шагов доступен потребителю только для чтения.9899**Py\_ssize\_t \*`suboffsets`**100101Массив из `Py_ssize_t` длиной [`ndim`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.ndim). Если `suboffsets[n] >= 0`, значения, хранящиеся вдоль n-го измерения, являются указателями, и значение suboffset определяет, сколько байтов добавить к каждому указателю после разыменования. Отрицательное значение suboffset указывает, что разыменование не должно выполняться (шаг в непрерывном блоке памяти).102103Если все suboffsets отрицательны (т.е. разыменование не требуется), то это поле должно быть NULL (значение по умолчанию).104105Такой тип представления массива используется библиотекой Python Imaging Library (PIL). Дополнительную информацию о доступе к элементам такого массива см. в разделе [сложные массивы](https://python-all.ru/3.4/c-api/buffer.html#complex-arrays).106107Массив смещений подмассивов доступен потребителю только для чтения.108109**void \*`internal`**110111Предназначено для внутреннего использования экспортирующим объектом. Например, экспортёр может переинтерпретировать это значение как целое число и использовать для хранения флагов о том, нужно ли освобождать массивы shape, strides и suboffsets при освобождении буфера. Потребитель НЕ ДОЛЖЕН изменять это значение.112113## Типы запросов буфера114115Буферы обычно получают, отправляя запрос на буфер экспортирующему объекту через [`PyObject_GetBuffer()`](https://python-all.ru/3.4/c-api/buffer.html#c.PyObject_GetBuffer). Поскольку сложность логической структуры памяти может сильно различаться, потребитель использует аргумент *flags* для указания точного типа буфера, который он может обработать.116117Все поля [`Py_buffer`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer) однозначно определяются типом запроса.118119### поля, не зависящие от запроса120121Следующие поля не зависят от *flags* и должны всегда заполняться корректными значениями: [`obj`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.obj), [`buf`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.buf), [`len`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.len), [`itemsize`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.itemsize), [`ndim`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.ndim).122123### только для чтения, формат124125> **`PyBUF_WRITABLE`**126>127> Управляет полем [`readonly`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.readonly). Если установлен, экспортёр ДОЛЖЕН предоставить буфер для записи, иначе сообщить об ошибке. В противном случае экспортёр МОЖЕТ предоставить либо буфер только для чтения, либо для записи, но выбор ДОЛЖЕН быть согласован для всех потребителей.128>129> **`PyBUF_FORMAT`**130>131> Управляет полем [`format`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.format). Если установлен, это поле ДОЛЖНО быть заполнено корректно. В противном случае это поле ДОЛЖНО быть *NULL*.132133[`PyBUF_WRITABLE`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBUF_WRITABLE) может быть объединён операцией | с любыми флагами из следующего раздела. Поскольку [`PyBUF_SIMPLE`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBUF_SIMPLE) определён как 0, [`PyBUF_WRITABLE`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBUF_WRITABLE) может использоваться как самостоятельный флаг для запроса простого буфера для записи.134135[`PyBUF_FORMAT`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBUF_FORMAT) может быть объединён операцией | с любыми флагами, кроме [`PyBUF_SIMPLE`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBUF_SIMPLE). Последний уже подразумевает формат `B` (беззнаковые байты).136137### форма, шаги, подсмещения138139Флаги, управляющие логической структурой памяти, перечислены в порядке убывания сложности. Обратите внимание, что каждый флаг содержит все биты флагов, расположенных ниже него.140141| Запрос | форма | шаги | подсмещения |142| --- | --- | --- | --- |143| `PyBUF_INDIRECT` | да | да | если необходимо |144| `PyBUF_STRIDES` | да | да | NULL |145| `PyBUF_ND` | да | NULL | NULL |146| `PyBUF_SIMPLE` | NULL | NULL | NULL |147148### запросы непрерывности149150Непрерывность по C или Fortran может быть явно запрошена, с информацией о шагах или без неё. Без информации о шагах буфер должен быть непрерывным по C.151152| Запрос | форма | шаги | подсмещения | непрерывность |153| --- | --- | --- | --- | --- |154| `PyBUF_C_CONTIGUOUS` | да | да | NULL | C |155| `PyBUF_F_CONTIGUOUS` | да | да | NULL | F |156| `PyBUF_ANY_CONTIGUOUS` | да | да | NULL | C или F |157| `PyBUF_ND` | да | NULL | NULL | C |158159### составные запросы160161Все возможные запросы полностью определяются некоторой комбинацией флагов из предыдущего раздела. Для удобства протокол буфера предоставляет часто используемые комбинации в виде отдельных флагов.162163В следующей таблице *U* означает неопределённую смежность. Потребитель должен вызвать [`PyBuffer_IsContiguous()`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBuffer_IsContiguous), чтобы определить смежность.164165| Запрос | форма | шаги | подсмещения | непрерывность | только для чтения | формат |166| --- | --- | --- | --- | --- | --- | --- |167| `PyBUF_FULL` | да | да | если необходимо | U | 0 | да |168| `PyBUF_FULL_RO` | да | да | если необходимо | U | 1 или 0 | да |169| `PyBUF_RECORDS` | да | да | NULL | U | 0 | да |170| `PyBUF_RECORDS_RO` | да | да | NULL | U | 1 или 0 | да |171| `PyBUF_STRIDED` | да | да | NULL | U | 0 | NULL |172| `PyBUF_STRIDED_RO` | да | да | NULL | U | 1 или 0 | NULL |173| `PyBUF_CONTIG` | да | NULL | NULL | C | 0 | NULL |174| `PyBUF_CONTIG_RO` | да | NULL | NULL | C | 1 или 0 | NULL |175176## Комплексные массивы177178### В стиле NumPy: форма и шаги179180Логическая структура массивов в стиле NumPy определяется [`itemsize`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.itemsize), [`ndim`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.ndim), [`shape`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.shape) и [`strides`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.strides).181182Если `ndim == 0`, то область памяти, на которую указывает [`buf`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.buf), интерпретируется как скаляр размера [`itemsize`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.itemsize). В таком случае и [`shape`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.shape), и [`strides`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.strides) равны *NULL*.183184Если [`strides`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.strides) равна *NULL*, массив интерпретируется как стандартный n-мерный C-массив. В противном случае потребитель должен обращаться к n-мерному массиву следующим образом:185186> `ptr = (char *)buf + indices[0] * strides[0] + ... + indices[n-1] * strides[n-1]`187>188> `item = *((typeof(item) *)ptr);`189190Как отмечалось выше, [`buf`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.buf) может указывать на любое место внутри фактического блока памяти. Экспортёр может проверить корректность буфера с помощью этой функции:191192```python193def verify_structure(memlen, itemsize, ndim, shape, strides, offset):194    """Проверить, что параметры представляют допустимый массив в пределах195       границ выделенной памяти:196           char *mem: начало физического блока памяти197           memlen: длина физического блока памяти198           смещение: (char *)buf - mem199    """200    if offset % itemsize:201        return False202    if offset < 0 or offset+itemsize > memlen:203        return False204    if any(v % itemsize for v in strides):205        return False206207    if ndim <= 0:208        return ndim == 0 and not shape and not strides209    if 0 in shape:210        return True211212    imin = sum(strides[j]*(shape[j]-1) for j in range(ndim)213               if strides[j] <= 0)214    imax = sum(strides[j]*(shape[j]-1) for j in range(ndim)215               if strides[j] > 0)216217    return 0 <= offset+imin and offset+imax+itemsize <= memlen218```219220### В стиле PIL: форма, шаги и suboffsets221222В дополнение к обычным элементам, массивы в стиле PIL могут содержать указатели, по которым нужно перейти, чтобы добраться до следующего элемента в измерении. Например, обычный трёхмерный C-массив `char v[2][2][3]` также можно рассматривать как массив из 2 указателей на 2 двумерных массива: `char (*v[2])[2][3]`. В представлении со смещениями подмассивов эти два указателя могут быть встроены в начало [`buf`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.buf), указывая на два массива `char x[2][3]`, которые могут располагаться в любом месте памяти.223224Ниже приведена функция, возвращающая указатель на элемент в N-мерном массиве, на который указывает N-мерный индекс, при наличии как ненулевых шагов (strides), так и субсмещений (suboffsets):225226```c227void *get_item_pointer(int ndim, void *buf, Py_ssize_t *strides,228                       Py_ssize_t *suboffsets, Py_ssize_t *indices) {229    char *pointer = (char*)buf;230    int i;231    for (i = 0; i < ndim; i++) {232        pointer += strides[i] * indices[i];233        if (suboffsets[i] >=0 ) {234            pointer = *((char**)pointer) + suboffsets[i];235        }236    }237    return (void*)pointer;238}239```240241## Функции, связанные с буфером242243#### `int PyObject_CheckBuffer(PyObject *obj)`244245Возвращает 1, если *obj* поддерживает интерфейс буфера, иначе 0. Если возвращается 1, это не гарантирует, что [`PyObject_GetBuffer()`](https://python-all.ru/3.4/c-api/buffer.html#c.PyObject_GetBuffer) выполнится успешно.246247#### `int PyObject_GetBuffer(PyObject *exporter, Py_buffer *view, int flags)`248249Отправляет запрос *exporter* на заполнение *view* в соответствии с *flags*. Если экспортёр не может предоставить буфер точного типа, он ДОЛЖЕН вызвать исключение `PyExc_BufferError`, установить `view->obj` в *NULL* и вернуть -1.250251При успехе заполняет *view*, устанавливает `view->obj` в новую ссылку на *exporter* и возвращает 0. В случае цепочечных поставщиков буферов, которые перенаправляют запросы одному объекту, `view->obj` МОЖЕТ ссылаться на этот объект вместо *exporter* (см. [*Структуры буферных объектов*](https://python-all.ru/3.4/c-api/typeobj.html#buffer-structs)).252253Успешные вызовы [`PyObject_GetBuffer()`](https://python-all.ru/3.4/c-api/buffer.html#c.PyObject_GetBuffer) должны быть парными с вызовами [`PyBuffer_Release()`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBuffer_Release), аналогично `malloc()` и `free()`. Поэтому после того, как потребитель закончил работу с буфером, [`PyBuffer_Release()`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBuffer_Release) должен быть вызван ровно один раз.254255#### `void PyBuffer_Release(Py_buffer *view)`256257Освобождает буфер *view* и уменьшает счётчик ссылок для `view->obj`. Эта функция ДОЛЖНА быть вызвана, когда буфер больше не используется, иначе могут возникнуть утечки ссылок.258259Вызов этой функции для буфера, который не был получен через [`PyObject_GetBuffer()`](https://python-all.ru/3.4/c-api/buffer.html#c.PyObject_GetBuffer), является ошибкой.260261#### `Py_ssize_t PyBuffer_SizeFromFormat(const char *)`262263Возвращает подразумеваемый [`itemsize`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.itemsize) из [`format`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.format). Эта функция ещё не реализована.264265#### `int PyBuffer_IsContiguous(Py_buffer *view, char order)`266267Возвращает 1, если память, определённая *view*, является непрерывной в стиле C (*order* равен `'C'`) или в стиле Fortran (*order* равен `'F'`) или любым из них (*order* равен `'A'`). Иначе возвращает 0.268269#### `void PyBuffer_FillContiguousStrides(int ndim, Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t itemsize, char order)`270271Заполняет массив *strides* байтовыми шагами непрерывного (в стиле C, если *order* равен `'C'`, или в стиле Fortran, если *order* равен `'F'`) массива заданной формы с заданным числом байт на элемент.272273#### `int PyBuffer_FillInfo(Py_buffer *view, PyObject *exporter, void *buf, Py_ssize_t len, int readonly, int flags)`274275Обрабатывает запросы буфера для экспортёра, который хочет предоставить *buf* размером *len* с настройкой возможности записи в соответствии с *readonly*. *buf* интерпретируется как последовательность байтов без знака.276277Аргумент *flags* указывает тип запроса. Эта функция всегда заполняет *view* в соответствии с flags, если только *buf* не был назначен только для чтения и в *flags* не установлен [`PyBUF_WRITABLE`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBUF_WRITABLE).278279При успехе устанавливает `view->obj` в новую ссылку на *exporter* и возвращает 0. В противном случае вызывает исключение `PyExc_BufferError`, устанавливает `view->obj` в *NULL* и возвращает -1;280281Если эта функция используется как часть [*getbufferproc*](https://python-all.ru/3.4/c-api/typeobj.html#buffer-structs), *exporter* ДОЛЖЕН быть установлен на экспортирующий объект, а *flags* должны передаваться без изменений. В противном случае *exporter* ДОЛЖЕН быть NULL.282