Перевірка документації по пам'яті:
об'єкти memoryview дозволяють коду Python отримувати доступ до внутрішніх даних об'єкта, що підтримує буферний протокол, без копіювання.
клас memoryview (obj)
Створіть перегляд пам'яті, який посилається на 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 для викриття внутрішніх даних буферного об'єкта без копіювання, однак, щоб зробити щось корисне з об'єктом (викликаючи методи, передбачені об'єктом), нам потрібно створити копію!
Зазвичай перегляд пам'яті (або старий буферний об'єкт) буде потрібен, коли ми маємо великий об'єкт, і фрагменти також можуть бути великими. Потреба в кращій ефективності буде присутня, якщо ми робимо великі фрагменти або робимо невеликі фрагменти, але велику кількість разів.
З наведеною вище схемою я не бачу, як це може бути корисним для будь-якої ситуації, якщо хтось не може пояснити мені, чого я тут пропускаю.
Edit1:
У нас є велика частина даних, ми хочемо обробити їх, просуваючись по них від початку до кінця, наприклад, витягуючи токени з початку буфера рядків, поки буфер не буде спожитий. буфер, і вказівник може бути переданий будь-якій функції, що очікує типу буфера. Як можна зробити щось подібне в python?
Люди пропонують обхідні шляхи, наприклад, багато функцій рядків і регулярних виразів беруть аргументи позиції, які можна використовувати для емуляції просування вказівника. З цим виникають дві проблеми: по-перше, це обхід, ви змушені змінити стиль кодування, щоб подолати недоліки, і по-друге: не всі функції мають аргументи позиції, наприклад функції регулярного виразу і startswith
роблять, encode()
/ decode()
не.
Інші можуть запропонувати завантажувати дані фрагментами або обробляти буфер невеликими сегментами, більшими за максимальний маркер. Гаразд, отже, ми знаємо про ці можливі обхідні шляхи, але ми повинні працювати більш природним чином у python, не намагаючись переробити стиль кодування відповідно до мови - чи не так?
Edit2:
Зразок коду зробить речі зрозумілішими. Це те, що я хочу зробити, і те, що, як я припускав, перегляд пам'яті дозволить мені зробити це на перший погляд. Давайте використовувати 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