type python3 py3 instalar has got expected bytes attribute argument _io python csv unicode python-2.7

python3 - ¿Cómo puedo usar io.StringIO() con el módulo csv?



stringio ruby (4)

Traté de respaldar un programa de Python 3 con 2.7, y tengo un extraño problema:

>>> import io >>> import csv >>> output = io.StringIO() >>> output.write("Hello!") # Fail: io.StringIO expects Unicode Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unicode argument expected, got ''str'' >>> output.write(u"Hello!") # This works as expected. 6L >>> writer = csv.writer(output) # Now let''s try this with the csv module: >>> csvdata = [u"Hello", u"Goodbye"] # Look ma, all Unicode! (?) >>> writer.writerow(csvdata) # Sadly, no. Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unicode argument expected, got ''str''

Según los documentos, io.StringIO() devuelve una secuencia en memoria para texto Unicode. Funciona correctamente cuando intento alimentarlo manualmente con una cadena Unicode. ¿Por qué falla junto con el módulo csv , incluso si todas las cadenas que se escriben son cadenas Unicode? ¿De dónde viene el str que causa la excepción?

(Sé que puedo usar StringIO.StringIO() , pero me pregunto qué le pasa a io.StringIO() en este escenario)


De la documentación de csv :

El módulo csv no admite directamente la lectura y escritura de Unicode, pero es un ahorro de 8 bits para algunos problemas con los caracteres ASCII NUL. De modo que puede escribir funciones o clases que manejen la codificación y decodificación siempre que evite codificaciones como UTF-16 que usan NUL. UTF-8 es recomendado.

Puede encontrar ejemplos de UnicodeReader , UnicodeWriter aquí http://docs.python.org/2/library/csv.html


El módulo Python 2.7 csv no es compatible con la entrada Unicode: vea la nota al principio de la documentación .

Parece que tendrá que codificar las cadenas Unicode para cadenas de bytes y usar io.BytesIO , en lugar de io.StringIO .

La sección de examples de la documentación incluye ejemplos para las clases de contenedor UnicodeReader y UnicodeWriter (gracias @AlexeyKachayev para el puntero).


Encontré esto cuando intenté publicar un archivo CSV a través de Flask directamente sin crear el archivo CSV en el sistema de archivos. Esto funciona:

import io import csv data = [[u''cell one'', u''cell two''], [u''cell three'', u''cell four'']] output = io.BytesIO() writer = csv.writer(output, delimiter='','') writer.writerows(data) your_csv_string = output.getvalue()

Ver también