Объекты 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