Объекты memoryview
позволяют коду Python получать доступ к внутренним данным объекта, который поддерживает буферный протокол, без копирования.
В Python объекты memoryview
обрабатываются встроенным классом memoryview()
. Встроенный класс memoryview()
имеет несколько своих методов.
Memoryview
имеет понятие элемента, который является атомарной единицей памяти, обрабатываемой исходным объектом obj
. Для многих простых типов, таких как bytes
и bytearray
, элемент является одним байтом, но другие типы, такие как array.array
может иметь более крупные элементы.
len(view)
равно длине memoryview.tolist
. Если view.ndim = 0
длина равна 1. Если view.ndim = 1
, длина равна количеству элементов в представлении. Для более высоких измерений длина будет равна длине представления вложенного списка. Атрибут memoryview.itemsize
даст вам количество байт в одном элементе.
Memoryview
поддерживает срезы и индексирование для предоставления своих данных. Одномерное нарезание приведет к подпредставлению:
>>> v = memoryview(b'abcefg') >>> v[1] 98 >>> v[-1] 103 >>> v[1:4] <memory at 0x7f3ddc9f4350> >>> bytes(v[1:4]) b'bce'
Если memoryview.format
является одним из собственных спецификаторов формата из модуля struct
, индексация с целым числом или кортежем целых чисел также поддерживается и возвращает один элемент с правильным типом. Одномерные memoryview
можно индексировать целочисленным или одноцелым кортежем. Многомерные memoryview
можно индексировать с помощью кортежей точно ndim
целых чисел, где ndim
- это число измерений. Представления нулевой размерности памяти можно индексировать с помощью пустого кортежа.
Вот пример с небайтовым форматом:
>>> import array >>> a = array.array('l', [-11111111, 22222222, -33333333, 44444444]) >>> m = memoryview(a) >>> m[0] -11111111 >>> m[-1] 44444444 >>> m[::2].tolist() [-11111111, -33333333]
Если базовый объект доступен для записи, то memoryview
поддерживает одномерное назначение среза. Изменение размера не допускается:
>>> data = bytearray(b'abcefg') >>> v = memoryview(data) >>> v.readonly False >>> v[0] = ord(b'z') >>> data bytearray(b'zbcefg') >>> v[1:4] = b'123' >>> data bytearray(b'z123fg') >>> v[2:3] = b'spam' Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: memoryview assignment: lvalue and rvalue have different structures >>> v[2:6] = b'spam' >>> data bytearray(b'z1spam')
Одномерное memoryviews
хешируемых (только для чтения) типов с форматами 'B'
, 'b'
или 'c'
также можно хешировать. Хеш определяется как: hash(m) == hash(m.tobytes())
:
>>> v = memoryview(b'abcefg') >>> hash(v) == hash(b'abcefg') True >>> hash(v[2:4]) == hash(b'ce') True >>> hash(v[::-2]) == hash(b'abcefg'[::-2]) True