Do czego służy typ bufora Python?

136

W bufferPythonie jest typ, ale nie wiem, jak go użyć.

W dokumentacji Pythona opis jest następujący:

buffer(object[, offset[, size]])

Argument obiektu musi być obiektem obsługującym interfejs wywołania bufora (taki jak łańcuchy, tablice i bufory). Zostanie utworzony nowy obiekt bufora, który odwołuje się do argumentu obiektu. Obiekt bufora będzie wycinkiem od początku obiektu (lub od określonego przesunięcia). Wycinek rozciągnie się do końca obiektu (lub będzie miał długość określoną przez argument rozmiar).

satoru
źródło

Odpowiedzi:

145

Przykładowe użycie:

>>> s = 'Hello world'
>>> t = buffer(s, 6, 5)
>>> t
<read-only buffer for 0x10064a4b0, size 5, offset 6 at 0x100634ab0>
>>> print t
world

Bufor w tym przypadku jest podciągiem, zaczynającym się na pozycji 6 i długości 5, i nie zajmuje dodatkowego miejsca w pamięci - odwołuje się do wycinka łańcucha.

Nie jest to zbyt przydatne w przypadku takich krótkich ciągów, ale może być konieczne, gdy używasz dużych ilości danych. W tym przykładzie zastosowano zmienną bytearray:

>>> s = bytearray(1000000)   # a million zeroed bytes
>>> t = buffer(s, 1)         # slice cuts off the first byte
>>> s[1] = 5                 # set the second element in s
>>> t[0]                     # which is now also the first element in t!
'\x05'

Może to być bardzo pomocne, jeśli chcesz mieć więcej niż jeden widok danych i nie chcesz (lub nie możesz) przechowywać wielu kopii w pamięci.

Zauważ, że bufferzostało zastąpione przez lepiej nazwane memoryvieww Pythonie 3, chociaż możesz użyć dowolnego w Pythonie 2.7.

Zauważ również, że nie możesz zaimplementować interfejsu bufora dla własnych obiektów bez zagłębiania się w API C, tj. Nie możesz tego zrobić w czystym Pythonie.

Scott Griffiths
źródło
Dziękuję za wyjaśnienie. Ale nadal nie do końca rozumiem, jaka jest różnica między buforowaniem a prostym krojeniem. Używanie s[6:11]również nie zajmuje dodatkowej przestrzeni dyskowej, czy się mylę?
satoru
9
Ogólnie rzecz biorąc, kawałek zajmie dodatkowe miejsce, więc tak s[6:11]będzie kopia. Jeśli ustawisz, t = s[6:11]a następnie del szwolnisz pamięć, która została zajęta s, udowadniając, że tzostała skopiowana. (Aby to zobaczyć, potrzebujesz większego si śledzić użycie pamięci w Pythonie). Jednak o wiele bardziej wydajne jest samo wykonanie kopii, jeśli nie ma tam dużo danych.
Scott Griffiths
1
Bardzo dziękuję :) Przy okazji, czy mógłbyś mi powiedzieć, jakiego narzędzia mogę użyć do śledzenia wykorzystania pamięci w Pythonie?
satoru
Informacje o zużyciu pamięci można znaleźć na przykład pod adresem stackoverflow.com/questions/110259 . Czasami najłatwiej jest po prostu obserwować użycie Pythona w Menedżerze zadań / Monitorze aktywności / top.
Scott Griffiths
13
Dla noobsów Pythona takich jak ja: bufor to widok pamięci w Pythonie 3
Dirk Bester
25

Myślę, że bufory są przydatne np. Podczas łączenia Pythona z natywnymi bibliotekami. (Guido van Rossum wyjaśnia bufferw tym poście na liście mailingowej ).

Na przykład numpy wydaje się używać bufora do wydajnego przechowywania danych:

import numpy
a = numpy.ndarray(1000000)

to a.datajest:

<read-write buffer for 0x1d7b410, size 8000000, offset 0 at 0x1e353b0>
Andre Holzner
źródło