textiowrapper modulenotfounderror libreria instalar got expected bytes argument python stringio bytesio cstringio

python - modulenotfounderror - Confundido acerca de StringIO, cStringIO y ByteIO



string argument expected, got ''bytes'' (1)

He buscado en Google y también busco en SO la diferencia entre estos módulos de búfer. Sin embargo, todavía no entiendo muy bien y creo que algunas de las publicaciones que leí están desactualizadas.

En Python 2.7.11, descargué un archivo binario de un formato específico usando r = requests.get(url) . Luego pasé StringIO.StringIO(r.content) , cStringIO.StringIO(r.content) y io.BytesIO(r.content) a una función diseñada para analizar el contenido.

Todos estos tres métodos están disponibles. Quiero decir, incluso si el archivo es binario, todavía es posible utilizar StringIO . ¿Por qué?

Otra cosa es con respecto a su eficiencia.

In [1]: import StringIO, cStringIO, io In [2]: from numpy import random In [3]: x = random.random(1000000) In [4]: %timeit y = cStringIO.StringIO(x) 1000000 loops, best of 3: 736 ns per loop In [5]: %timeit y = StringIO.StringIO(x) 1000 loops, best of 3: 283 µs per loop In [6]: %timeit y = io.BytesIO(x) 1000 loops, best of 3: 1.26 ms per loop

Como se ilustra arriba, cStringIO > StringIO > BytesIO .

Encontré que alguien mencionó que io.BytesIO siempre hace una copia nueva que cuesta más tiempo. Pero también hay algunas publicaciones que indican que esto se solucionó en versiones posteriores de Python.

Entonces, ¿puede alguien hacer una comparación exhaustiva entre estos IO , tanto en Python 2.xy 3.x?

Algunas de las referencias que encontré:

  • https://trac.edgewall.org/ticket/12046

    io.StringIO requiere una cadena Unicode. io.BytesIO requiere una cadena de bytes. StringIO.StringIO permite unicode o una cadena de bytes. cStringIO.StringIO requiere una cadena codificada como una cadena de bytes.

Pero cStringIO.StringIO(''abc'') no cStringIO.StringIO(''abc'') ningún error.

Hay un parche de corrección en esta publicación en 2014.

  • Un montón de mensajes de SO no enumerados aquí.

Aquí están los resultados de Python 2.7 para el ejemplo de Eric

%timeit cStringIO.StringIO(u_data) 1000000 loops, best of 3: 488 ns per loop %timeit cStringIO.StringIO(b_data) 1000000 loops, best of 3: 448 ns per loop %timeit StringIO.StringIO(u_data) 1000000 loops, best of 3: 1.15 µs per loop %timeit StringIO.StringIO(b_data) 1000000 loops, best of 3: 1.19 µs per loop %timeit io.StringIO(u_data) 1000 loops, best of 3: 304 µs per loop # %timeit io.StringIO(b_data) # error # %timeit io.BytesIO(u_data) # error %timeit io.BytesIO(b_data) 10000 loops, best of 3: 77.5 µs per loop

En cuanto a 2.7, cStringIO.StringIO y StringIO.StringIO son mucho más eficientes que io .


Debe usar io.StringIO o io.BytesIO , dependiendo de si sus datos son binarios, tanto en python 2 como en 3, para la compatibilidad hacia adelante (esto es todo lo que 3 tiene para ofrecer).

Aquí hay una mejor prueba (para python 2 y 3), que no incluye los costos de conversión de numpy a str / bytes

import numpy as np import string b_data = np.random.choice(list(string.printable), size=1000000).tobytes() u_data = b_data.decode(''ascii'') u_data = u''/u2603'' + u_data[1:] # add a non-ascii character

Y entonces:

import io %timeit io.StringIO(u_data) %timeit io.StringIO(b_data) %timeit io.BytesIO(u_data) %timeit io.BytesIO(b_data)

En Python 2, también puedes probar:

import StringIO, cStringIO %timeit cStringIO.StringIO(u_data) %timeit cStringIO.StringIO(b_data) %timeit StringIO.StringIO(u_data) %timeit StringIO.StringIO(b_data)

Algunos de estos se estrellarán, quejándose de personajes no ascii

Resultados de Python 3.5:

>>> %timeit io.StringIO(u_data) 100 loops, best of 3: 8.61 ms per loop >>> %timeit io.StringIO(b_data) TypeError: initial_value must be str or None, not bytes >>> %timeit io.BytesIO(u_data) TypeError: a bytes-like object is required, not ''str'' >>> %timeit io.BytesIO(b_data) The slowest run took 6.79 times longer than the fastest. This could mean that an intermediate result is being cached 1000000 loops, best of 3: 344 ns per loop

Resultados de Python 2.7 (ejecutar en una máquina diferente):

>>> %timeit io.StringIO(u_data) 1000 loops, best of 3: 304 µs per loop >>> %timeit io.StringIO(b_data) TypeError: initial_value must be unicode or None, not str >>> %timeit io.BytesIO(u_data) TypeError: ''unicode'' does not have the buffer interface >>> %timeit io.BytesIO(b_data) 10000 loops, best of 3: 77.5 µs per loop

>>> %timeit cStringIO.StringIO(u_data) UnicodeEncodeError: ''ascii'' codec cant encode character u''/u2603'' in position 0: ordinal not in range(128) >>> %timeit cStringIO.StringIO(b_data) 1000000 loops, best of 3: 448 ns per loop >>> %timeit StringIO.StringIO(u_data) 1000000 loops, best of 3: 1.15 µs per loop >>> %timeit StringIO.StringIO(b_data) 1000000 loops, best of 3: 1.19 µs per loop