2011-11-03 19 views
58

No soy un profesional y me he estado rascando la cabeza por entender para qué se usa exactamente StringIO. He estado buscando en internet algunos ejemplos. Sin embargo, casi todos los ejemplos son muy abstractos. Y solo muestran "cómo" usarlo. ¿Pero ninguno de ellos muestra "por qué" y "en qué circunstancias" uno debería usarlo? Gracias de antemano¿Para qué sirve StringIO en python en realidad?

P.s. no se debe confundir con esta pregunta en stackoverflow: StringIO Usage que compara cadena y StringIo.

Respuesta

75

Se usa cuando tiene alguna API que solo toma archivos, pero necesita usar una cadena. Por ejemplo, para comprimir una cadena utilizando el módulo gzip en Python 2:

import gzip 
import StringIO 

stringio = StringIO.StringIO() 
gzip_file = gzip.GzipFile(fileobj=stringio, mode='w') 
gzip_file.write('Hello World') 
gzip_file.close() 

stringio.getvalue() 
+0

en otras palabras: 'typing' pato: D – Abdelouahab

+1

Desde Python 3.2, el módulo gzip tiene funciones comprimen los datos directamente. (Sin embargo, cualquier biblioteca de código abierto bien conocido que actualmente necesita StringIO probablemente crecerá tales funciones después de algún tiempo, por lo que en lugar de buscar un nuevo ejemplo que voy a dejar aquí gzip.) –

27

StringIO le ofrece acceso similar a un archivo a las cadenas, por lo que puede utilizar un módulo existente que se ocupa de un archivo y no cambiar casi nada y hacer que funcione con cadenas.

Por ejemplo, supongamos que tiene un registrador que escribe cosas en un archivo y desea enviar el resultado del registro a través de la red. Puede leer el archivo y escribir su contenido en la red, o puede escribir el registro en un objeto StringIO y enviarlo a su destino de red sin tocar el sistema de archivos. StringIO hace que sea fácil hacerlo de la primera manera y luego cambiar a la segunda manera.

12

En los casos donde se desea un objeto de tipo fichero que actúa como un archivo, sino que está escrito a un búfer de cadenas en memoria: StringIO es la herramienta. Si está creando cadenas de gran tamaño, como documentos de texto sin formato y haciendo una gran cantidad de concatenación de cadenas, puede que le resulte más fácil simplemente usar StringIO en lugar de un montón de operaciones de tipo mystr += 'more stuff\n'.

+1

También he encontrado 'StringIO' sea considerablemente más rápido si se trata de varios megabytes de datos de carácter cuando se compara con expresiones como 'mystr + = "más cosas \ n"' dentro de un bucle, especialmente si usted puede usar 'cStringIO.StringIO' en lugar de simplemente' io.StringIO '. – SeldomNeedy

8

par de cosas que personalmente he utilizado para:

  1. de archivo entero de almacenamiento en caché. Tengo un script que lee archivos PDF y hace validaciones de varias cosas sobre ellos. La biblioteca PDF que estoy utilizando toma un archivo abierto en su constructor de documento. Originalmente abrí el PDF que estaba interesado en leer, sin embargo, cuando lo cambié para leer todo el archivo a la vez en la memoria y luego pasé un objeto StringIO a la biblioteca PDF, el tiempo de ejecución de mi script se redujo a la mitad.

  2. Impresión diferida. El mismo script imprime un encabezado antes de cada PDF que lee. Sin embargo, puedo especificar en la línea de comandos si ignorar ciertas pruebas que están en su archivo de configuración o solo incluir algunas. Si ignoro todas las pruebas para un PDF determinado, no quiero que se imprima el encabezado, pero no sabré cuántas pruebas ejecuté hasta que termine de ejecutar las pruebas (las pruebas también pueden definirse dinámicamente). Así que capturo el encabezado en un objeto StringIO cambiando sys.stdout para apuntar a él, y cada vez que ejecuto una prueba, compruebo si ese objeto tiene algo. Si es así, lo imprimo y lo reinicio en vacío. Voila, solo los PDF que tienen pruebas tienen encabezados impresos.

7

yo sólo he utilizado StringIO en la práctica por dos cosas:

  • Para unidad de prueba de un script que hace un montón de print ing, mediante la reorientación de sys.stdout a una instancia StringIO para facilitar el análisis;
  • Para crear un documento XML bien formado y garantizado (una solicitud API personalizada) usando ElementTree y luego write para enviar a través de una conexión HTTP.

No es que se necesitan StringIO menudo, pero a veces es muy útil.

0

Django tiene una función call_command que se utiliza para llamar a los comandos de administración. Esta función imprime la salida en stdout y no devuelve ningún valor. Si desea saber si el comando se ejecutó correctamente o no, debe buscar el resultado y decidir.

Usando StringIO, puede capturar la salida y comprobar si se desea o no la salida.

with io.StringIO() as output: 
    call_command('custom_command', stdout=output) 
    if 'Success' not in output.getvalue(): 
     print('Custom command failed...')