python stringio

python - ¿Cuándo se usa StringIO, a diferencia de unirse a una lista de cadenas?



stringio python 3 (4)

Usar StringIO como un buffer de cadena es más lento que usar list como buffer.

¿Cuándo se usa StringIO?

from io import StringIO def meth1(string): a = [] for i in range(100): a.append(string) return ''''.join(a) def meth2(string): a = StringIO() for i in range(100): a.write(string) return a.getvalue() if __name__ == ''__main__'': from timeit import Timer string = "This is test string" print(Timer("meth1(string)", "from __main__ import meth1, string").timeit()) print(Timer("meth2(string)", "from __main__ import meth2, string").timeit())

Resultados:

16.7872819901 18.7160351276


Bueno, no sé si me gustaría llamarlo usándolo como un "buffer", solo estás multiplicando una cadena 100 veces, en dos formas complicadas. Aquí hay una forma sencilla:

def meth3(string): return string * 100

Si lo agregamos a su prueba:

if __name__ == ''__main__'': from timeit import Timer string = "This is test string" # Make sure it all does the same: assert(meth1(string) == meth3(string)) assert(meth2(string) == meth3(string)) print(Timer("meth1(string)", "from __main__ import meth1, string").timeit()) print(Timer("meth2(string)", "from __main__ import meth2, string").timeit()) print(Timer("meth3(string)", "from __main__ import meth3, string").timeit())

Resulta ser mucho más rápido como una bonificación:

21.0300650597 22.4869811535 0.811429977417

Si desea crear un conjunto de cadenas y luego unirlas, meth1 () es la forma correcta. No tiene sentido escribirlo en StringIO, que es algo completamente diferente, a saber, una cadena con una interfaz de flujo similar a un archivo.


La principal ventaja de StringIO es que puede usarse donde se esperaba un archivo. Para que pueda hacer, por ejemplo (para Python 2):

import sys import StringIO out = StringIO.StringIO() sys.stdout = out print "hi, I''m going out" sys.stdout = sys.__stdout__ print out.getvalue()


Otro enfoque basado en el enfoque de Lennart Regebro. Esto es más rápido que el método de lista (meth1)

def meth4(string): a = StringIO(string * 100) contents = a.getvalue() a.close() return contents if __name__ == ''__main__'': from timeit import Timer string = "This is test string" print(Timer("meth1(string)", "from __main__ import meth1, string").timeit()) print(Timer("meth2(string)", "from __main__ import meth2, string").timeit()) print(Timer("meth3(string)", "from __main__ import meth3, string").timeit()) print(Timer("meth4(string)", "from __main__ import meth4, string").timeit())

Resultados (seg.):

meth1 = 7.731315963647944

meth2 = 9.609279402186985

meth3 = 0.26534052061106195

meth4 = 2.915035489152274


Si mide la velocidad, debe usar cStringIO .

De los docs :

El módulo cStringIO proporciona una interfaz similar a la del módulo StringIO. El uso intensivo de los objetos StringIO.StringIO se puede hacer más eficiente si se utiliza la función StringIO () de este módulo.

Pero el objetivo de StringIO es ser un objeto similar a un archivo , para cuando algo lo espere y no desee usar archivos reales.

Editar: me di cuenta de que utiliza from io import StringIO , por lo que probablemente esté en Python> = 3 o al menos 2.6. El StringIO y cStringIO por separado se han ido en Py3. No estoy seguro de qué implementación utilizaron para proporcionar el io.StringIO. Hay io.BytesIO también.