Проверка документации по memoryview:
Объекты memoryview позволяют коду Python получать доступ к внутренним данным объекта, который поддерживает протокол буфера, без копирования.
класс memoryview (объект)
Создайте представление памяти, которое ссылается на obj. obj должен поддерживать протокол буфера. Встроенные объекты, поддерживающие протокол буфера, включают байты и массив байтов.
Затем нам дается пример кода:
>>> v = memoryview(b'abcefg')
>>> v[1]
98
>>> v[-1]
103
>>> v[1:4]
<memory at 0x7f3ddc9f4350>
>>> bytes(v[1:4])
b'bce'
Цитата окончена, теперь давайте рассмотрим подробнее:
>>> b = b'long bytes stream'
>>> b.startswith(b'long')
True
>>> v = memoryview(b)
>>> vsub = v[5:]
>>> vsub.startswith(b'bytes')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'memoryview' object has no attribute 'startswith'
>>> bytes(vsub).startswith(b'bytes')
True
>>>
Итак, что я понял из вышесказанного:
Мы создаем объект memoryview для предоставления внутренних данных объекта буфера без копирования, однако, чтобы сделать что-нибудь полезное с объектом (путем вызова методов, предоставленных объектом), мы должны создать копию!
Обычно memoryview (или старый буферный объект) потребуется, когда у нас есть большой объект, и срезы тоже могут быть большими. Потребность в большей эффективности будет присутствовать, если мы делаем большие ломтики или маленькие ломтики, но большое количество раз.
С приведенной выше схемой я не понимаю, как она может быть полезна в любой ситуации, если только кто-нибудь не объяснит мне, чего мне здесь не хватает.
Edit1:
У нас есть большой кусок данных, мы хотим обработать его, продвигаясь по нему от начала до конца, например, извлекая токены из начала строкового буфера до тех пор, пока буфер не будет использован. В термине C это продвигает указатель через buffer, а указатель может быть передан любой функции, ожидающей типа буфера. Как можно сделать что-то подобное в Python?
Люди предлагают обходные пути, например, многие строковые и регулярные функции принимают аргументы позиции, которые можно использовать для имитации продвижения указателя. С этим есть две проблемы: во-первых, это обходной путь, вы вынуждены изменить свой стиль кодирования, чтобы преодолеть недостатки, и, во-вторых, не все функции имеют аргументы позиции, например функции регулярных выражений и startswith
do, encode()
/ decode()
not.
Другие могут предложить загружать данные порциями или обрабатывать буфер небольшими сегментами, размер которых превышает максимальный токен. Итак, мы знаем об этих возможных обходных путях, но мы должны работать в Python более естественным образом, не пытаясь изменить стиль кодирования в соответствии с языком - не так ли?
Edit2:
Образец кода проясняет ситуацию. Это то, что я хочу сделать, и то, что я предполагал, с первого взгляда позволит мне сделать memoryview. Давайте использовать pmview (правильное представление памяти) для функциональности, которую я ищу:
tokens = []
xlarge_str = get_string()
xlarge_str_view = pmview(xlarge_str)
while True:
token = get_token(xlarge_str_view)
if token:
xlarge_str_view = xlarge_str_view.vslice(len(token))
# vslice: view slice: default stop paramter at end of buffer
tokens.append(token)
else:
break