write utf8 unicodeencodeerror u201c u2010 print files codecs charmap characters python encoding decode encode

utf8 - python write utf 8 files



UnicodeEncodeError: el códec ''charmap'' no puede codificar: los mapas de los caracteres a<undefined>, la función de impresión (6)

Basado en la respuesta de Dirk Stöcker, aquí hay una función de envoltura limpia para la función de impresión de Python 3. Úselo como lo haría con la impresión.

Como una ventaja adicional, en comparación con las otras respuestas, esto no imprimirá su texto como bytearray (''b "content"''), sino como cadenas normales (''content''), debido al último paso de decodificación.

def uprint(*objects, sep='' '', end=''/n'', file=sys.stdout): enc = file.encoding if enc == ''UTF-8'': print(*objects, sep=sep, end=end, file=file) else: f = lambda obj: str(obj).encode(enc, errors=''backslashreplace'').decode(enc) print(*map(f, objects), sep=sep, end=end, file=file) uprint(''foo'') uprint(u''Antonín Dvořák'') uprint(''foo'', ''bar'', u''Antonín Dvořák'')

Esta pregunta ya tiene una respuesta aquí:

Estoy escribiendo un programa de Python (Python 3.3) para enviar datos a una página web usando el método POST. Sobre todo para el proceso de depuración, obtengo el resultado de la página y lo visualizo en la pantalla con print() función de print() .

El código es así:

conn.request("POST", resource, params, headers) response = conn.getresponse() print(response.status, response.reason) data = response.read() print(data.decode(''utf-8''));

el HTTPResponse .read() devuelve un elemento de bytes que codifica la página (que es un documento UTF-8 bien formateado) Parecía correcto hasta que dejé de usar IDLE GUI para Windows y usé la consola de Windows. La página devuelta tiene un carácter U + 2014 (em-dash) que la función de impresión se traduce bien en la GUI de Windows (presumo la página de códigos 1252) pero no en la consola de Windows (página de códigos 850). Dado el strict comportamiento predeterminado, recibo el siguiente error:

UnicodeEncodeError: ''charmap'' codec can''t encode character ''/u2014'' in position 10248: character maps to <undefined>

Podría arreglarlo usando este código bastante feo:

print(data.decode(''utf-8'').encode(''cp850'',''replace'').decode(''cp850''))

Ahora reemplaza el carácter ofensivo "-" con a ? . No es el caso ideal (un guión debería ser un mejor reemplazo) pero lo suficientemente bueno para mi propósito.

Hay varias cosas que no me gustan de mi solución.

  1. El código es feo con toda esa decodificación, codificación y decodificación.
  2. Resuelve el problema solo para este caso. Si transfiero el programa a un sistema usando alguna otra codificación (latin-1, cp437, de regreso a cp1252, etc.) debería reconocer la codificación del objetivo. No es asi. (Por ejemplo, cuando se usa nuevamente la GUI IDLE, el emdash también se pierde, lo que no sucedió antes)
  3. Sería más agradable si el emdash se traduce a un guión en lugar de un golpe de interrogación.

El problema no es el emdash (puedo pensar en varias formas de resolver ese problema en particular), sino que necesito escribir un código robusto. Estoy alimentando la página con datos de una base de datos y esos datos pueden regresar. Puedo anticipar muchos otros casos conflictivos: un ''Á'' U + 00c1 (que es posible en mi base de datos) podría traducirse en CP-850 (codificador de la consola de DOS / Windows para los idiomas de Europa occidental) pero no en CP-437 (codificación para EE. UU. Inglés, que es el predeterminado en muchas instalaciones de Windows).

Entonces, la pregunta:

¿Hay alguna solución más agradable que haga que mi código sea independiente de la codificación de la interfaz de salida?


Para fines de depuración, puede usar print(repr(data)) .

Para mostrar texto, siempre imprima Unicode. No codifique la codificación de caracteres de su entorno como cp850 dentro de su script. Para decodificar la respuesta http, consulte Una buena forma de obtener el conjunto de caracteres / codificación de una respuesta HTTP en Python .

Para imprimir Unicode en la consola de Windows, puede usar el paquete win-unicode-console .


Profundicé en esto y encontré que las mejores soluciones están aquí.

http://blog.notdot.net/2010/07/Getting-unicode-right-in-Python

En mi caso, resolví "UnicodeEncodeError: el códec ''charmap'' no puede codificar el carácter"

código original:

print("Process lines, file_name command_line %s/n"% command_line))

Nuevo código:

print("Process lines, file_name command_line %s/n"% command_line.encode(''utf-8''))


Si está utilizando la línea de comandos de Windows para imprimir los datos, debe usar

chcp 65001

¡Esto funcionó para mí!


Si usa Python 3.6 (posiblemente 3.5 o posterior), ya no me da ese error. Tuve un problema similar, porque estaba usando v3.4, pero desapareció después de que desinstalé y reinstalé.


Veo tres soluciones para esto:

  1. Cambia la codificación de salida, por lo que siempre dará salida a UTF-8. Consulte, por ejemplo, la configuración de la codificación correcta cuando se corta el stdout en Python , pero no pude conseguir que estos ejemplos funcionen.

  2. El siguiente código de ejemplo hace que el resultado conozca su juego de caracteres objetivo.

    # -*- coding: utf-8 -*- import sys print sys.stdout.encoding print u"Stöcker".encode(sys.stdout.encoding, errors=''replace'') print u"Стоескер".encode(sys.stdout.encoding, errors=''replace'')

    Este ejemplo reemplaza adecuadamente cualquier carácter no imprimible en mi nombre con un signo de interrogación.

    Si crea una función de impresión personalizada, por ejemplo llamada myprint , utilizando esos mecanismos para codificar la salida correctamente, puede simplemente reemplazar la impresión con myprint donde sea necesario sin hacer que todo el código se vea feo.

  3. Restablezca la codificación de salida globalmente al comienzo del software:

    La página http://www.macfreek.nl/memory/Encoding_of_Python_stdout tiene un buen resumen de qué hacer para cambiar la codificación de salida. Especialmente la sección "StreamWriter Wrapper around Stdout" es interesante. Básicamente dice cambiar la función de codificación de E / S de la siguiente manera:

    En Python 2:

    if sys.stdout.encoding != ''cp850'': sys.stdout = codecs.getwriter(''cp850'')(sys.stdout, ''strict'') if sys.stderr.encoding != ''cp850'': sys.stderr = codecs.getwriter(''cp850'')(sys.stderr, ''strict'')

    En Python 3:

    if sys.stdout.encoding != ''cp850'': sys.stdout = codecs.getwriter(''cp850'')(sys.stdout.buffer, ''strict'') if sys.stderr.encoding != ''cp850'': sys.stderr = codecs.getwriter(''cp850'')(sys.stderr.buffer, ''strict'')

    Si se utiliza en CGI para generar HTML, puede reemplazar ''strict'' por ''xmlcharrefreplace'' para obtener etiquetas HTML codificadas para caracteres no imprimibles.

    Siéntase libre de modificar los enfoques, estableciendo diferentes codificaciones, .... Tenga en cuenta que todavía no funcionará para generar datos no especificados. Por lo tanto, los datos, las entradas y los textos se deben convertir correctamente en unicode:

    # -*- coding: utf-8 -*- import sys import codecs sys.stdout = codecs.getwriter("iso-8859-1")(sys.stdout, ''xmlcharrefreplace'') print u"Stöcker" # works print "Stöcker".decode("utf-8") # works print "Stöcker" # fails