2010-08-06 9 views
118

Hay un tipo buffer en python, pero no sé cómo puedo usarlo.¿Para qué sirve el tipo de búfer de Python?

En el Python doc la descripción es:

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

El argumento objeto debe ser un objeto que soporta la interfaz de llamada tampón (tales como cadenas, matrices y tampones). Se creará un nuevo objeto de búfer que hace referencia al argumento del objeto. El objeto de búfer será un corte desde el principio del objeto (o desde el desplazamiento especificado). El corte se extenderá hasta el final del objeto (o tendrá una longitud dada por el argumento de tamaño).

Respuesta

120

Un ejemplo de uso:

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

El tampón en este caso es una sub-secuencia, empezando en la posición 6 con una longitud de 5, y no se necesita espacio de almacenamiento adicional - que hace referencia a una rebanada de la cuerda.

Esto no es muy útil para cadenas cortas como esta, pero puede ser necesario cuando se usan grandes cantidades de datos. En este ejemplo se utiliza un mutable 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' 

Esto puede ser muy útil si desea tener más de una vista de los datos y no quiere (o no puede) contener múltiples copias en la memoria.

Tenga en cuenta que buffer ha sido reemplazado por el mejor nombre memoryview en Python 3, aunque puede usar cualquiera de ellos en Python 2.7.

Tenga en cuenta también que no puede implementar una interfaz de búfer para sus propios objetos sin profundizar en la API de C, es decir, no puede hacerlo en Python puro.

+0

Gracias por su explicación. Pero todavía no entiendo muy bien cuál es la diferencia entre el almacenamiento en búfer y el corte simple. Usar 's [6:11]' no requiere espacio de almacenamiento adicional, ¿me equivoco? – satoru

+8

En general, un sector tendrá un almacenamiento adicional, por lo que sí 's [6:11]' será una copia. Si establece 't = s [6:11]' y luego 'del s', libera la memoria que fue tomada por' s', lo que demuestra que 't' se copió. (Para ver esto necesitas un 's' más grande y rastrear el uso de la memoria de Python). Sin embargo, es mucho más eficiente simplemente hacer la copia si no hay mucha información involucrada. –

+0

Muchas gracias :) Por cierto, ¿podría decirme qué herramienta puedo usar para rastrear el uso de memoria de Python? – satoru

21

Creo que los búferes son, p. útil cuando se conecta python a bibliotecas nativas. (Guido van Rossum explica buffer en this mailinglist post).

Por ejemplo, numpy parece utilizar memoria intermedia para el almacenamiento de datos eficiente:

import numpy 
a = numpy.ndarray(1000000) 

la a.data es un:

<read-write buffer for 0x1d7b410, size 8000000, offset 0 at 0x1e353b0> 
+0

La lista de correo sin duda vale la pena leerla. – Robino