Wofür ist der Python-Puffertyp?

136

Es gibt einen bufferTyp in Python, aber ich weiß nicht, wie ich ihn verwenden kann.

Im Python-Dokument lautet die Beschreibung:

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

Das Objektargument muss ein Objekt sein, das die Pufferaufrufschnittstelle unterstützt (z. B. Zeichenfolgen, Arrays und Puffer). Es wird ein neues Pufferobjekt erstellt, das auf das Objektargument verweist. Das Pufferobjekt ist ein Slice vom Anfang des Objekts (oder vom angegebenen Offset). Das Slice erstreckt sich bis zum Ende des Objekts (oder hat eine Länge, die durch das Größenargument angegeben wird).

Satoru
quelle

Antworten:

145

Ein Anwendungsbeispiel:

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

Der Puffer ist in diesem Fall eine Unterzeichenfolge, die an Position 6 mit der Länge 5 beginnt, und benötigt keinen zusätzlichen Speicherplatz - er verweist auf einen Teil der Zeichenfolge.

Dies ist für solche kurzen Zeichenfolgen nicht sehr nützlich, kann jedoch bei Verwendung großer Datenmengen erforderlich sein. In diesem Beispiel wird eine veränderbare Variable verwendet 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'

Dies kann sehr hilfreich sein, wenn Sie mehr als eine Ansicht der Daten haben möchten und nicht mehrere Kopien im Speicher halten möchten (oder können).

Beachten Sie, dass dies in Python 3 bufferdurch das besser benannte ersetzt wurde memoryview, obwohl Sie beides in Python 2.7 verwenden können.

Beachten Sie auch, dass Sie keine Pufferschnittstelle für Ihre eigenen Objekte implementieren können, ohne sich mit der C-API zu befassen, dh Sie können dies nicht in reinem Python tun.

Scott Griffiths
quelle
Danke für Ihre Erklärung. Aber ich verstehe immer noch nicht ganz, was der Unterschied zwischen Pufferung und einfachem Schneiden ist. Die Verwendung s[6:11]beansprucht auch keinen zusätzlichen Speicherplatz. Liege ich falsch?
Satoru
9
Im Allgemeinen benötigt ein Slice zusätzlichen Speicherplatz, also ist ja s[6:11]eine Kopie. Wenn Sie t = s[6:11]and einstellen del s, wird der Speicher sfreigegeben, tder von kopiert wurde, und es wird bewiesen, dass dieser kopiert wurde. (Um dies zu sehen, benötigen Sie eine größere sund verfolgen die Speichernutzung von Python). Es ist jedoch viel effizienter, die Kopie nur zu erstellen, wenn nicht viele Daten beteiligt sind.
Scott Griffiths
1
Vielen Dank :) Übrigens, können Sie mir bitte sagen, mit welchem ​​Tool ich die Speichernutzung von Python verfolgen kann?
Satoru
Informationen zur Speichernutzung finden Sie beispielsweise unter stackoverflow.com/questions/110259 . Manchmal ist es am einfachsten, die Verwendung von Python im Task-Manager / Aktivitätsmonitor / oben zu beobachten.
Scott Griffiths
13
Für Python-Noobs wie mich: Puffer ist Memoryview in Python 3
Dirk Bester
25

Ich denke, Puffer sind zB nützlich, wenn Python mit nativen Bibliotheken verbunden wird. (Guido van Rossum erklärt bufferin diesem Mailinglistenbeitrag ).

Zum Beispiel scheint numpy Puffer für eine effiziente Datenspeicherung zu verwenden:

import numpy
a = numpy.ndarray(1000000)

das a.dataist ein:

<read-write buffer for 0x1d7b410, size 8000000, offset 0 at 0x1e353b0>
Andre Holzner
quelle