Sprawdzanie dokumentacji dotyczącej podglądu pamięci:
obiekty memoryview umożliwiają kodowi Python dostęp do wewnętrznych danych obiektu, który obsługuje protokół bufora, bez kopiowania.
klasa memoryview (obj)
Utwórz widok pamięci, który odwołuje się do obj. obj musi obsługiwać protokół bufora. Wbudowane obiekty, które obsługują protokół bufora, obejmują bajty i bajt.
Następnie otrzymujemy przykładowy kod:
>>> v = memoryview(b'abcefg')
>>> v[1]
98
>>> v[-1]
103
>>> v[1:4]
<memory at 0x7f3ddc9f4350>
>>> bytes(v[1:4])
b'bce'
Cytat zakończony, teraz przyjrzyjmy się bliżej:
>>> 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
>>>
Więc co z powyższego wyciągam:
Tworzymy obiekt memoryview, aby ujawnić wewnętrzne dane obiektu buforowego bez kopiowania, jednak aby zrobić cokolwiek pożytecznego z obiektem (przez wywołanie metod dostarczonych przez obiekt), musimy utworzyć kopię!
Zwykle memoryview (lub stary obiekt bufora) byłby potrzebny, gdy mamy duży obiekt, a plasterki również mogą być duże. Potrzeba lepszej wydajności byłaby obecna, gdybyśmy robili duże plasterki lub robili małe plasterki, ale dużą liczbę razy.
Z powyższym schematem nie widzę, jak może być przydatny w obu sytuacjach, chyba że ktoś może mi wyjaśnić, czego tutaj brakuje.
Edycja1:
Mamy dużą porcję danych, chcemy ją przetworzyć, przechodząc przez nią od początku do końca, na przykład wyodrębniając tokeny od początku bufora ciągów do momentu zużycia bufora. W języku C oznacza to przesunięcie wskaźnika przez bufor, a wskaźnik można przekazać do dowolnej funkcji, która oczekuje typu buforu. Jak można zrobić coś podobnego w Pythonie?
Ludzie sugerują obejście tego problemu, na przykład wiele funkcji ciągów i wyrażeń regularnych przyjmuje argumenty pozycji, które mogą być używane do emulacji przesuwania wskaźnika. Są z tym dwa problemy: po pierwsze jest to obejście, jesteś zmuszony zmienić styl kodowania, aby przezwyciężyć niedociągnięcia, a po drugie: nie wszystkie funkcje mają argumenty pozycji, na przykład funkcje regex i startswith
wykonaj, encode()
/ decode()
nie.
Inni mogą sugerować ładowanie danych porcjami lub przetwarzanie buforu w małych segmentach większych niż maksymalny token. OK, więc jesteśmy świadomi tych możliwych obejść, ale powinniśmy pracować w Pythonie w bardziej naturalny sposób, bez próby naginania stylu kodowania, aby pasował do języka - czyż nie?
Edit2:
Przykładowy kod sprawiłby, że wszystko było jaśniejsze. To jest to, co chcę zrobić i na pierwszy rzut oka założyłem, że widok wspomnień pozwoli mi zrobić. Użyjmy pmview (właściwego widoku pamięci) dla funkcji, której szukam:
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