Que no se puede crear un utf-8 archivo csv en Python.

Estoy tratando de leer es docs, y en el sección de ejemplos, dice:

Para todas las otras codificaciones de los siguientes
UnicodeReader y UnicodeWriter
las clases pueden ser utilizados. Ellos toman un
adicional parámetro de codificación en su
constructor y asegúrese de que el
los datos pasan de la real lector o escritor
codificado como UTF-8:

Aceptar. Así que tengo este código:

values = (unicode("Ñ", "utf-8"), unicode("é", "utf-8"))
f = codecs.open('eggs.csv', 'w', encoding="utf-8")
writer = UnicodeWriter(f)
writer.writerow(values)

Y me sale este error:

line 159, in writerow
    self.stream.write(data)
  File "/usr/lib/python2.6/codecs.py", line 686, in write
    return self.writer.write(data)
  File "/usr/lib/python2.6/codecs.py", line 351, in write
    data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 22: ordinal not in range(128)

Por favor alguien puede darme una luz para que yo pueda entender qué diablos estoy haciendo mal ya que establece que todos la codificación de todas partes antes de llamar a UnicodeWriter clase?

class UnicodeWriter:
    """
    A CSV writer which will write rows to CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
        # Redirect output to a queue
        self.queue = cStringIO.StringIO()
        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
        self.stream = f
        self.encoder = codecs.getincrementalencoder(encoding)()

    def writerow(self, row):
        self.writer.writerow([s.encode("utf-8") for s in row])
        # Fetch UTF-8 output from the queue ...
        data = self.queue.getvalue()
        data = data.decode("utf-8")
        # ... and reencode it into the target encoding
        data = self.encoder.encode(data)
        # write to the target stream
        self.stream.write(data)
        # empty queue
        self.queue.truncate(0)

    def writerows(self, rows):
        for row in rows:
            self.writerow(row)
  • Es seens el problema es con los codecs.abrir. Cuando me lo quite y solo uso abierto, funciona. Por qué?

4 Comentarios

  1. 14

    Usted no tiene que usar codecs.open; UnicodeWriter toma de entrada Unicode y se encarga de la codificación de todo en UTF-8. Cuando UnicodeWriter escribe en el identificador de archivo que ha pasado, todo lo que ya está en la codificación UTF-8 (por lo tanto funciona con un archivo normal que abrió con open).

    Mediante codecs.open, básicamente, convertir sus objetos Unicode UTF-8 cuerdas en UnicodeWriter, a continuación, intente volver a codificar estas cadenas en UTF-8, de nuevo, como si estas cadenas contenidas cadenas Unicode, que, obviamente, se produce un error.

    • Cómo fue exactamente lo que yo trate de codificar dos veces, ya que acaba de abrir un archivo objeto? No códec.abrir abre un archivo de objetos de flujo, indicando que la codificación?
    • De acuerdo a la documentación de codecs.open: «Abrir un archivo codificado usando el modo y el retorno de una envuelto versión de dar transparente de codificación/decodificación de.». En otras palabras, si usted abre un archivo para escritura con codecs.open, va a codificar de forma transparente todo lo que se escriba en él a UTF-8 en primer lugar.
    • Yo pensé: «proporcionar transparente de codificación/decodificación» es demasiado subjetivo. Yo creo que si me necesitan entender más, sólo tengo que leer la fuente.
  2. 1

    Como usted ha descubierto funciona si uso llanura abierta.

    La razón de esto es que se trató de codificar en UTF-8 dos veces. Una vez en

    f = codecs.open('eggs.csv', 'w', encoding="utf-8")

    y, a continuación, más adelante en UnicodeWriter.writeRow

    # ... and reencode it into the target encoding
    data = self.encoder.encode(data)

    Para comprobar que esto funciona usar su código original y outcomment esa línea.

    Saludos

  3. 0

    No necesita de «doble-codificar» todo.

    Su aplicación debe funcionar completamente en Unicode.

    Hacer su codificación sólo en el codecs.open para escribir bytes UTF-8 a un archivo externo. No otra codificación dentro de la aplicación.

    • Csv módulo no funciona con unicode. Para hacer mi código de trabajo, tengo que quitar exactamente los codecs.abrir.
    • Si CSV no funciona con unicode, entonces usted no puede utilizarlo para crear UTF-8, a menos que usted desea escribir su propia UTF-8 encoder.

Dejar respuesta

Please enter your comment!
Please enter your name here