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

buffer.md

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

1> **Источник:** https://python-all.ru/3.0/c-api/buffer.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Буферные объекты89Объекты Python, реализованные на C, могут экспортировать «буферный интерфейс». Эти функции могут использоваться объектом для предоставления своих данных в сыром, ориентированном на байты формате. Клиенты объекта могут использовать буферный интерфейс для прямого доступа к данным объекта без необходимости их предварительного копирования.1011Два примера объектов, поддерживающих буферный интерфейс: bytes и arrays. Объект bytes предоставляет содержимое символов в байт-ориентированной форме буферного интерфейса. Массив также может предоставлять своё содержимое, однако следует отметить, что элементы массива могут быть многобайтовыми.1213Примером использования буферного интерфейса является метод `write()` файлового объекта. Любой объект, который может экспортировать последовательность байтов через буферный интерфейс, может быть записан в файл. Существует ряд кодов формата для [`PyArg_ParseTuple`](https://python-all.ru/3.0/c-api/arg.html#PyArg_ParseTuple), которые работают с буферным интерфейсом объекта, возвращая данные из целевого объекта.1415Дополнительная информация о буферном интерфейсе приведена в разделе [*Структуры буферных объектов*](https://python-all.ru/3.0/c-api/typeobj.html#buffer-structs), в описании [`PyBufferProcs`](https://python-all.ru/3.0/c-api/typeobj.html#PyBufferProcs).1617Буферные объекты полезны как способ предоставления данных из буферного интерфейса другого объекта программисту Python. Они также могут использоваться как механизм среза без копирования. Благодаря возможности ссылаться на блок памяти, можно довольно легко предоставить любые данные программисту Python. Память может быть большим постоянным массивом в расширении C, сырым блоком памяти для манипуляций перед передачей в библиотеку операционной системы или использоваться для передачи структурированных данных в их родном, внутрипамятном формате.1819**\[Py\_buffer\]`Py_buffer`**2021**\[buf\]void \*`buf`**2223Указатель на начало памяти объекта.2425**Py\_ssize\_t `len`**2627Общая длина памяти в байтах.2829**\[readonly\]int `readonly`**3031Индикатор того, является ли буфер доступным только для чтения.3233**const char \*`format`**3435Строка, завершающаяся нулём3637*NULL*3839, в синтаксисе стиля модуля4041[`struct`](https://python-all.ru/3.0/library/struct.html#module-struct)4243, задающая содержимое элементов, доступных через буфер. Если это4445*NULL*4647, то предполагается4849`"B"`5051(беззнаковые байты).5253**\[ndim\]int `ndim`**5455Количество измерений, которые память представляет как многомерный массив. Если оно равно 0,5657[`strides`](https://python-all.ru/3.0/c-api/buffer.html#strides)5859и6061[`suboffsets`](https://python-all.ru/3.0/c-api/buffer.html#suboffsets)6263должны быть6465*NULL*6667.6869**\[shape\]Py\_ssize\_t \*`shape`**7071Массив7273`Py_ssize_t`7475длиной7677[`ndim`](https://python-all.ru/3.0/c-api/buffer.html#ndim)7879, задающий форму памяти как многомерного массива. Обратите внимание, что8081`((*shape)[0] * ... * (*shape)[ndims-1])*itemsize`8283должно быть равно8485`len`8687.8889**\[strides\]Py\_ssize\_t \*`strides`**9091Массив9293`Py_ssize_t`9495длиной9697[`ndim`](https://python-all.ru/3.0/c-api/buffer.html#ndim)9899, задающий количество байтов, которое нужно пропустить, чтобы перейти к новому элементу в каждом измерении.100101**\[suboffsets\]Py\_ssize\_t \*`suboffsets`**102103Массив `Py_ssize_t` длиной [`ndim`](https://python-all.ru/3.0/c-api/buffer.html#ndim). Если эти числа suboffset больше или равны 0, то значение, хранящееся по указанному измерению, является указателем, а значение suboffset определяет, сколько байтов добавить к указателю после разыменования. Отрицательное значение suboffset означает, что разыменование не должно выполняться (шаг в непрерывном блоке памяти).104105Вот функция, которая возвращает указатель на элемент в N-мерном массиве, на который указывает N-мерный индекс, при наличии как ненулевых strides, так и suboffsets:106107```c108void *get_item_pointer(int ndim, void *buf, Py_ssize_t *strides,109    Py_ssize_t *suboffsets, Py_ssize_t *indices) {110    char *pointer = (char*)buf;111    int i;112    for (i = 0; i < ndim; i++) {113        pointer += strides[i] * indices[i];114        if (suboffsets[i] >=0 ) {115            pointer = *((char**)pointer) + suboffsets[i];116        }117    }118    return (void*)pointer;119 }120```121122**\[itemsize\]Py\_ssize\_t `itemsize`**123124Это хранилище для размера элемента (в байтах) каждого элемента разделяемой памяти. Технически оно необязательно, так как его можно получить с помощью125126[`PyBuffer_SizeFromFormat`](https://python-all.ru/3.0/c-api/buffer.html#PyBuffer_SizeFromFormat)127128, однако экспортёр может знать эту информацию без разбора строки формата, и необходимо знать размер элемента для правильной интерпретации шагов (striding). Поэтому сохранение его более удобно и быстрее.129130**\[internal\]void \*`internal`**131132Это поле предназначено для внутреннего использования экспортирующим объектом. Например, оно может быть переинтерпретировано как целое число экспортером и использоваться для хранения флагов о том, нужно ли освобождать массивы shape, strides и suboffsets при освобождении буфера. Потребитель никогда не должен изменять это значение.133134## Функции, связанные с буферами135136**\[PyObject\_CheckBuffer\]int `PyObject_CheckBuffer`([PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*obj*)**137138Возвращает 1, если139140*obj*141142поддерживает буферный интерфейс, иначе 0.143144**\[PyObject\_GetBuffer\]int `PyObject_GetBuffer`([PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*obj*, [PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*view*, int *flags*)**145146Экспортирует *obj* в [`Py_buffer`](https://python-all.ru/3.0/c-api/buffer.html#Py_buffer), *view*. Эти аргументы никогда не должны быть *NULL*. Аргумент *flags* представляет собой битовое поле, указывающее, с каким типом буфера готов работать вызывающий код, и, следовательно, какой тип буфера разрешено возвращать экспортёру. Буферный интерфейс допускает сложные возможности совместного использования памяти, но некоторые вызывающие стороны могут не справиться со всей сложностью и могут захотеть проверить, позволит ли экспортёр им использовать более простое представление своей памяти.147148Некоторые экспортёры могут не иметь возможности разделять память любым возможным способом и могут вызывать ошибки, чтобы сообщить некоторым потребителям, что что-то просто невозможно. Эти ошибки должны быть `BufferError`, если только нет другой ошибки, которая на самом деле вызывает проблему. Экспортёр может использовать информацию из flags, чтобы упростить заполнение структуры [`Py_buffer`](https://python-all.ru/3.0/c-api/buffer.html#Py_buffer) значениями, отличными от стандартных, и/или вызвать ошибку, если объект не может поддерживать более простое представление своей памяти.1491500 возвращается в случае успеха, -1 – при ошибке.151152В следующей таблице приведены возможные значения аргумента *flags*.153154| Флаг | Описание |155| --- | --- |156| `PyBUF_SIMPLE` | Это состояние флага по умолчанию. Возвращаемый буфер может иметь или не иметь память для записи. Формат данных будет считаться беззнаковыми байтами. Это «автономная» константа флага. Её никогда не нужно комбинировать с другими с помощью оператора '\|'. Экспортёр вызовет ошибку, если не сможет предоставить такой непрерывный буфер байтов. |157| `PyBUF_WRITABLE` | Возвращаемый буфер должен быть доступен для записи. Если это не так, вызывается ошибка. |158| `PyBUF_STRIDES` | Это подразумевает `PyBUF_ND`. Возвращаемый буфер должен предоставлять информацию о шагах (т.е. шаги не могут быть NULL). Используется, когда потребитель может работать со страйдед-массивами (с разрывами). Работа с шагами автоматически подразумевает, что доступна информация о форме. Экспортёр может вызвать ошибку, если страйдед-представление данных невозможно (например, без suboffsets). |159| `PyBUF_ND` | Возвращаемый буфер должен предоставлять информацию о форме. Память считается C-стиль непрерывной (последнее измерение меняется быстрее всего). Экспортёр может вызвать ошибку, если не может предоставить такой непрерывный буфер. Если этот флаг не задан, форма будет *NULL*. |160| `PyBUF_C_CONTIGUOUS` `PyBUF_F_CONTIGUOUS` `PyBUF_ANY_CONTIGUOUS` | Эти флаги указывают, что возвращаемый буфер должен быть соответственно C-непрерывным (последнее измерение меняется быстрее всего), Fortran-непрерывным (первое измерение меняется быстрее всего) или любым из них. Все эти флаги подразумевают `PyBUF_STRIDES` и гарантируют, что структура информации о шагах будет заполнена корректно. |161| `PyBUF_INDIRECT` | Этот флаг указывает, что возвращаемый буфер должен содержать информацию suboffsets (может быть NULL, если suboffsets не нужны). Используется, когда потребитель может работать с косвенной адресацией массива, подразумеваемой этими suboffsets. Этот флаг подразумевает `PyBUF_STRIDES`. |162| `PyBUF_FORMAT` | Возвращаемый буфер должен содержать настоящую информацию о формате, если этот флаг указан. Это используется, когда потребитель собирается проверять, какой именно тип данных хранится. Экспортёр всегда должен быть способен предоставить эту информацию по запросу. Если формат явно не запрошен, он должен быть возвращён как *NULL* (что означает `'B'`, то есть беззнаковые байты). |163| `PyBUF_STRIDED` | Это эквивалентно `(PyBUF_STRIDES \| PyBUF_WRITABLE)`. |164| `PyBUF_STRIDED_RO` | Это эквивалентно `(PyBUF_STRIDES)`. |165| `PyBUF_RECORDS` | Это эквивалентно `(PyBUF_STRIDES \| PyBUF_FORMAT \| PyBUF_WRITABLE)`. |166| `PyBUF_RECORDS_RO` | Это эквивалентно `(PyBUF_STRIDES \| PyBUF_FORMAT)`. |167| `PyBUF_FULL` | Это эквивалентно `(PyBUF_INDIRECT \| PyBUF_FORMAT \| PyBUF_WRITABLE)`. |168| `` PyBUF_FULL_RO` `` | Это эквивалентно `(PyBUF_INDIRECT \| PyBUF_FORMAT)`. |169| `PyBUF_CONTIG` | Это эквивалентно `(PyBUF_ND \| PyBUF_WRITABLE)`. |170| `PyBUF_CONTIG_RO` | Это эквивалентно `(PyBUF_ND)`. |171172**\[PyBuffer\_Release\]void `PyBuffer_Release`([PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*obj*, [Py\_buffer](https://python-all.ru/3.0/c-api/buffer.html#Py_buffer) *\*view*)**173174Освобождает буфер175176*view*177178для объекта179180*obj*181182. Должен вызываться, когда буфер больше не используется, так как это может освободить память.183184**\[PyBuffer\_SizeFromFormat\]Py\_ssize\_t `PyBuffer_SizeFromFormat`(const char *\**)**185186Возвращает неявный187188`~Py_buffer.itemsize`189190из форматной строки struct191192`~Py_buffer.format`193194.195196**\[PyObject\_CopyToObject\]int `PyObject_CopyToObject`([PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*obj*, void *\*buf*, Py\_ssize\_t *len*, char *fortran*)**197198Копирует199200*len*201202байт данных, на которые указывает непрерывный блок памяти203204*buf*205206, в буфер, экспортируемый obj. Буфер, разумеется, должен быть доступен для записи. Возвращает 0 при успехе и -1 с вызовом ошибки при неудаче. Если у объекта нет буфера для записи, вызывается ошибка. Если207208*fortran*209210равен211212`'F'`213214, то в случае многомерного объекта данные копируются в массив в стиле Fortran (первое измерение меняется быстрее всего). Если215216*fortran*217218равен219220`'C'`221222, данные копируются в стиле C (последнее измерение меняется быстрее всего). Если223224*fortran*225226равен227228`'A'`229230, то разницы нет, и копирование выполняется наиболее эффективным способом.231232**\[PyBuffer\_IsContiguous\]int `PyBuffer_IsContiguous`([Py\_buffer](https://python-all.ru/3.0/c-api/buffer.html#Py_buffer) *\*view*, char *fortran*)**233234Возвращает 1, если память, определяемая235236*view*237238, является смежной в стиле C (239240*fortran*241242равно243244`'C'`245246) или в стиле Fortran (247248*fortran*249250равно251252`'F'`253254), или любого из них (255256*fortran*257258равно259260`'A'`261262). В противном случае возвращает 0.263264**\[PyBuffer\_FillContiguousStrides\]void `PyBuffer_FillContiguousStrides`(int *ndim*, Py\_ssize\_t *\*shape*, Py\_ssize\_t *\*strides*, Py\_ssize\_t *itemsize*, char *fortran*)**265266Заполняет массив267268*strides*269270байтовыми шагами непрерывного (в стиле C, если271272*fortran*273274равно275276`'C'`277278, или в стиле Фортрана, если279280*fortran*281282равно283284`'F'`285286) массива заданной формы с заданным количеством байтов на элемент.287288**\[PyBuffer\_FillInfo\]int `PyBuffer_FillInfo`([Py\_buffer](https://python-all.ru/3.0/c-api/buffer.html#Py_buffer) *\*view*, void *\*buf*, Py\_ssize\_t *len*, int *readonly*, int *infoflags*)**289290Заполняет структуру буферной информации291292*view*293294корректно для экспортёра, который может передавать только смежный блок памяти из «unsigned bytes» заданной длины. Возвращает 0 при успехе и -1 (с порождением исключения) при ошибке.295296## Объекты MemoryView297298Объект memoryview – это расширенный буферный объект, который может заменить буферный объект (но не обязан, так как тот может оставаться простым одномерным объектом memoryview объект). Он, в отличие от [`Py_buffer`](https://python-all.ru/3.0/c-api/buffer.html#Py_buffer), является объектом Python (предоставляется как [`memoryview`](https://python-all.ru/3.0/library/stdtypes.html#memoryview) в [`builtins`](https://python-all.ru/3.0/library/builtins.html#module-builtins)), поэтому его можно использовать в коде Python.299300**\[PyMemoryView\_FromObject\][PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject)\* `PyMemoryView_FromObject`([PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject) *\*obj*)**301302Возвращает объект memoryview из объекта, который определяет буферный интерфейс.303