A cosa serve il tipo di buffer Python?


136

C'è un buffertipo in Python, ma non so come posso usarlo.

Nel documento Python la descrizione è:

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

L'argomento object deve essere un oggetto che supporta l'interfaccia di chiamata del buffer (come stringhe, array e buffer). Verrà creato un nuovo oggetto buffer che fa riferimento all'argomento oggetto. L'oggetto buffer sarà una sezione dall'inizio dell'oggetto (o dall'offset specificato). La sezione si estenderà fino alla fine dell'oggetto (o avrà una lunghezza data dall'argomento size).

Risposte:


145

Un esempio di utilizzo:

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

Il buffer in questo caso è una sottostringa, che inizia dalla posizione 6 con lunghezza 5 e non occupa spazio di archiviazione aggiuntivo, ma fa riferimento a una sezione della stringa.

Questo non è molto utile per stringhe brevi come questa, ma può essere necessario quando si utilizzano grandi quantità di dati. Questo esempio utilizza un mutabile 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'

Questo può essere molto utile se vuoi avere più di una vista sui dati e non vuoi (o non puoi) conservare più copie in memoria.

Si noti che bufferè stato sostituito dal nome migliore memoryviewin Python 3, sebbene sia possibile utilizzarlo in Python 2.7.

Nota anche che non puoi implementare un'interfaccia buffer per i tuoi oggetti senza approfondire l'API C, cioè non puoi farlo in Python puro.


Grazie per la tua spiegazione. Ma non riesco ancora a capire qual è la differenza tra buffering e slicing semplice. Anche l'utilizzo s[6:11]non richiede spazio di archiviazione aggiuntivo, sbaglio?
satoru,

9
In generale una porzione richiederà ulteriore spazio di archiviazione, quindi sì s[6:11]sarà una copia. Se si imposta t = s[6:11]e quindi del s, libera la memoria che è stata presa s, dimostrando che è tstato copiato. (Per vederlo hai bisogno di uno più grande se traccia l'utilizzo della memoria di Python). È comunque molto più efficiente solo fare la copia se non ci sono molti dati coinvolti.
Scott Griffiths,

1
Grazie mille :) A proposito, potresti dirmi quale strumento posso usare per tenere traccia dell'utilizzo della memoria di Python?
satoru,

Per l'utilizzo della memoria, ad esempio, stackoverflow.com/questions/110259 . A volte è più semplice osservare l'utilizzo di Python in Task Manager / Activity Monitor / top.
Scott Griffiths,

13
Per Python nessuno come me: buffer è memoryview in Python 3
Dirk Bester

25

Penso che i buffer siano ad esempio utili quando si interfaccia Python con le librerie native. (Guido van Rossum spiega bufferin questo post della mailinglist ).

Ad esempio, numpy sembra utilizzare il buffer per un'archiviazione efficiente dei dati:

import numpy
a = numpy.ndarray(1000000)

il a.dataè una:

<read-write buffer for 0x1d7b410, size 8000000, offset 0 at 0x1e353b0>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.