Как использовать функцию memoryview() в Python

Использование функции memoryview() в Python обеспечивает прямой доступ для чтения и записи к байтовым данным объекта без необходимости их предварительного копирования.

Что такое memoryview() в Python?

memoryview в Python — это встроенный объект, который позволяет коду получать доступ к внутренним данным объекта, поддерживающего протокол буфера, без копирования. Прежде чем мы углубимся в представление памяти, нам сначала нужно понять буферный протокол в Python.

Функция memoryview в Python

Буферный протокол Python

Это протокол, обеспечивающий доступ к внутренним данным объекта. Внутренние данные могут быть массивом памяти или буфером. Этот протокол позволяет одному объекту предоставлять свои данные другим объектам, а другие объекты получают доступ к этим данным(буферу) без промежуточного копирования.

Но проблема в том, что если мы не можем получить доступ к этому протоколу со стандартной кодовой базой, это доступно нам на уровне C-API. Итак, в python, если мы хотим предоставить тот же протокол в python, нам нужно использовать memoryview.

Что такое memory view

Представление памяти — это безопасный способ раскрыть этот буферный протокол. Он позволяет нам получить доступ к внутренним буферам объекта, создав объект memory view в Python.

Синтаксис

Здесь obj — это внутренние данные, которые нужно показать. Но он должен поддерживать буферный протокол.

Возвращаемое значение

Функция memoryview() возвращает объект представления памяти данного объекта.

См. следующий пример кода.

Смотрите вывод.

Теперь мы увидим, как мы можем изменить внутренние данные с помощью memoryview.

См. второй пример.

Вывод:

В приведенной выше программе сначала мы создаем массив байтов.

Затем мы создаем memory view и обновляем представление памяти, а теперь снова печатаем массив, чтобы увидеть разницу.

Почему buffer protocol и memoryview так важны?

Представления памяти Python полезны тем, что их можно нарезать без копирования базовых данных, в отличие от bytes/str.

Кроме того, следует помнить, что всякий раз, когда мы выполняем какое-либо действие над объектом (вызываем функцию объекта, разрезаем массив), нам (или Python) необходимо создать копию объекта.

Если у нас есть большие данные для работы (например, двоичные данные изображения), мы будем без необходимости создавать копии огромных кусков данных, которые практически бесполезны.

Используя протокол буфера, мы можем предоставить другому объекту доступ для использования/изменения больших данных без их копирования. Это позволяет программе использовать меньше памяти и увеличивает скорость выполнения.

Объекты memoryview отлично подходят, когда вам нужны подмножества двоичных данных, которые должны поддерживать только индексацию. Вместо того, чтобы брать фрагменты (и создавать новые, потенциально большие) объекты для передачи другому API, вы можете взять объект memoryview. Одним из таких примеров API может быть модуль struct.

Вместо того, чтобы передавать срез объекта больших байтов для анализа упакованных значений C, вы передаете представление памяти только той области, из которой вам нужно извлечь значения.

Объекты memoryview фактически изначально поддерживают распаковку структуры; вы можете нацелить область базового объекта байтов с помощью среза, а затем использовать .cast() для «интерпретации» базовых байтов как длинных целых чисел, значений с плавающей запятой или n-мерных списков целых чисел.

Это обеспечивает очень эффективную интерпретацию формата двоичного файла без необходимости создания дополнительных копий байтов.

Оцените статью

Автор статей и разработчик, делюсь знаниями.

Программирование на Python