Cuando intento imprimir una cadena Unicode en una consola de Windows, aparece un UnicodeEncodeError: 'charmap' codec can't encode character ....
error. Supongo que esto se debe a que la consola de Windows no acepta caracteres solo Unicode. ¿Cuál es la mejor manera de evitar esto? ¿Hay alguna manera de hacer que Python imprima automáticamente en ?
lugar de fallar en esta situación?
Editar: estoy usando Python 2.5.
Nota: la respuesta de @ LasseV.Karlsen con la marca de verificación está desactualizada (desde 2008). ¡Utilice las soluciones / respuestas / sugerencias a continuación con cuidado!
La respuesta de @JFSebastian es más relevante a partir de hoy (6 de enero de 2016).
Respuestas:
Nota: Esta respuesta está desactualizada (desde 2008). ¡Utilice la solución a continuación con cuidado!
Aquí hay una página que detalla el problema y una solución (busque en la página el texto Wrapping sys.stdout en una instancia ):
PrintFails - Python Wiki
Aquí hay un extracto de código de esa página:
Hay más información en esa página, vale la pena leer.
fuente
sys.stdout
, imprime las cosas incorrectas. Por ejemplo, seu'\u2013'
convierte enû
lugar de en-dash.cp437
es diferente de la página de códigos ANSI de Windows comocp1252
. El código no solucionaUnicodeEncodeError: 'charmap' codec can't encode character
error y puede conducir a mojibake por ejemplo,ا©
está en silencio reemplazado con╪º⌐
.Actualización: Python 3.6 implementa PEP 528: cambie la codificación de la consola de Windows a UTF-8 : la consola predeterminada en Windows ahora aceptará todos los caracteres Unicode. Internamente, utiliza la misma API Unicode que el
win-unicode-console
paquete mencionado a continuación .print(unicode_string)
Debería funcionar ahora.El error significa que los caracteres Unicode que está intentando imprimir no se pueden representar utilizando la
chcp
codificación de caracteres de la consola actual ( ). La página de códigos suele ser una codificación de 8 bits, comocp437
que puede representar solo ~ 0x100 caracteres de ~ 1M caracteres Unicode:La consola de Windows acepta caracteres Unicode e incluso puede mostrarlos (solo BMP) si la fuente correspondiente está configurada .
WriteConsoleW()
API debe usarse como se sugiere en la respuesta de @Daira Hopwood . Se puede llamar de forma transparente, es decir, no es necesario y no debe modificar sus scripts si usa elwin-unicode-console
paquete :Vea ¿Cuál es el trato con Python 3.4, Unicode, diferentes idiomas y Windows?
Si es suficiente para reemplazar todos los caracteres no codificables
?
en su caso, entonces podría configurarPYTHONIOENCODING
envvar :En Python 3.6+, la codificación especificada por
PYTHONIOENCODING
envvar se ignora para las memorias intermedias de consola interactivas a menos quePYTHONLEGACYWINDOWSIOENCODING
envvar esté configurado en una cadena no vacía.fuente
print('\u4E01')
,print('\u6b63')
).A pesar de las otras respuestas de sonido plausible que sugieren cambiar la página de códigos a 65001, eso no funciona . (Además, cambiar la codificación predeterminada usando no
sys.setdefaultencoding
es una buena idea ).Consulte esta pregunta para obtener detalles y el código que funciona.
fuente
win-unicode-console
El paquete Python (basado en su código) permite evitar modificar su script si imprime Unicode directamente usando elpy -mrun your_script.py
comando .Si no está interesado en obtener una representación confiable de los caracteres malos, puede usar algo como esto (trabajando con python> = 2.6, incluyendo 3.x):
Los caracteres incorrectos en la cadena se convertirán en una representación que la consola de Windows pueda imprimir.
fuente
.encode('utf8').decode(sys.stdout.encoding)
conduce a mojibake, por ejemplo,u"\N{EM DASH}".encode('utf-8').decode('cp437')
->ΓÇö
print(s.encode('utf-8'))
puede ser una mejor manera de evitar errores de compilación. En cambio, obtienes \ xNN salida para caracteres no imprimibles, que fue suficiente para mis mensajes de diagnóstico.El siguiente código hará que Python realice la salida a la consola como UTF-8 incluso en Windows.
La consola mostrará bien los caracteres en Windows 7, pero en Windows XP no los mostrará bien, pero al menos funcionará y, lo más importante, tendrá una salida consistente de su script en todas las plataformas. Podrá redirigir la salida a un archivo.
El siguiente código se probó con Python 2.6 en Windows.
fuente
import win32console
fuera de unatry
y más tarde lo hace de forma condicional dentro de unatry
? ¿No es inútil (el primeroimport
)Simplemente ingrese este código en la línea de comando antes de ejecutar el script python:
fuente
Como la respuesta de Giampaolo Rodolà, pero aún más sucia: realmente, realmente tengo la intención de pasar mucho tiempo (pronto) entendiendo todo el tema de las codificaciones y cómo se aplican a las consolas Windoze,
Por el momento solo quería sthg, lo que significaría que mi programa NO CRASH, y lo entendí ... y también que no implicaba importar demasiados módulos exóticos (en particular, estoy usando Jython, así que la mitad del tiempo un Python De hecho, el módulo no está disponible).
NB "pr" es más corto de escribir que "print" (y bastante más corto de escribir que "safeprint") ...!
fuente
Para Python 2 intente:
Para Python 3 intente:
O prueba win-unicode-console:
fuente
TL; DR:
Me encontré con esto yo mismo, trabajando en un bot de chat Twitch (IRC). (Python 2.7 más reciente)
Quería analizar los mensajes de chat para responder ...
pero también imprímalos de forma segura en la consola en un formato legible para humanos:
Esto corrigió el problema de los
UnicodeEncodeError: 'charmap'
errores de lanzamiento de bot y reemplazó los caracteres unicode con?
.fuente
La causa de su problema NO es que la consola Win no esté dispuesta a aceptar Unicode (como lo hace, ya que supongo que Win2k por defecto). Es la codificación predeterminada del sistema. Pruebe este código y vea lo que le ofrece:
si dice ascii, ahí está tu causa ;-) Tienes que crear un archivo llamado sitecustomize.py y ponerlo en la ruta de Python (lo puse en /usr/lib/python2.5/site-packages, pero eso es diferente en Win: es c: \ python \ lib \ site-packages o algo así, con el siguiente contenido:
y quizás también desee especificar la codificación en sus archivos:
Editar: se puede encontrar más información en el excelente libro Inmersión en Python
fuente
Algo relacionado en la respuesta de JF Sebastian, pero más directo.
Si tiene este problema al imprimir en la consola / terminal, haga lo siguiente:
fuente
set PYTHONIOENCODING=UTF-8
puede conducir a mojibake si la consola usa una codificación diferente, como cp437.cp65001
Tiene varios problemas . Para imprimir Unicode en la consola de Windows, se debe usar la API de Unicode (WriteConsoleW()
) como se sugiere en mi respuesta, dondePYTHONIOENCODING
solo se usa para reemplazar caracteres que no se pueden representar en la página de códigos OEM actual?
(WriteConsoleW()
funciona incluso para tales caracteres).PYTHONIOENCODING
se puede usar si la salida se redirige a un archivo.Python 3.6 windows7: hay varias formas de iniciar una python: puede usar la consola de python (que tiene un logotipo de python) o la consola de windows (está escrito cmd.exe).
No pude imprimir caracteres utf8 en la consola de Windows. Imprimir caracteres utf-8 me arroja este error:
Después de intentar y no entender la respuesta anterior, descubrí que solo era un problema de configuración. Haga clic derecho en la parte superior de las ventanas de la consola cmd, en la pestaña
font
elija la consola lucida.fuente
James Sulak preguntó:
Otras soluciones recomiendan que intentemos modificar el entorno de Windows o reemplazar la
print()
función de Python . La respuesta a continuación se acerca al cumplimiento de la solicitud de Sulak.En Windows 7, se puede hacer que Python 3.5 imprima Unicode sin lanzar un de la
UnicodeEncodeError
siguiente manera:En lugar de:
print(text)
sustituto:
print(str(text).encode('utf-8'))
En lugar de lanzar una excepción, Python ahora muestra caracteres Unicode no imprimibles como códigos hexadecimales \ xNN , por ejemplo:
Halmalo n \ xe2 \ x80 \ x99 \ xc3 \ xa9tait plus qu \ xe2 \ x80 \ x99un punto negro
En vez de
Halmalo n'était plus qu'un point noir
Por supuesto, este último es preferible ceteris paribus , pero por lo demás el primero es completamente preciso para los mensajes de diagnóstico. Debido a que muestra Unicode como valores de bytes literales, el primero también puede ayudar a diagnosticar problemas de codificación / decodificación.
Nota: La
str()
llamada anterior es necesaria porque, de lo contrarioencode()
, Python rechaza un carácter Unicode como una tupla de números.fuente