open - Python, Unicode y la consola de Windows
python unicode utf-8 (13)
A pesar de las otras respuestas de sonido plausible que sugieren cambiar la página de códigos a 65001, eso
bugs.python.org/issue1602
.
(Además, cambiar la codificación predeterminada utilizando
sys.setdefaultencoding
no
es
una buena idea
).
Vea esta pregunta para obtener detalles y el código que sí funciona.
Cuando intento imprimir una cadena Unicode en una consola de Windows, obtengo un
UnicodeEncodeError: ''charmap'' codec can''t encode character ....
error.
Supongo que esto se debe a que la consola de Windows no acepta caracteres solo de Unicode.
¿Cuál es la mejor manera de evitar esto?
¿Hay alguna manera de hacer que Python imprima automáticamente un
?
En lugar de fallar en esta situación?
Edición: estoy usando Python 2.5.
Nota: La respuesta de @ LasseV.Karlsen con la marca de verificación está un poco desactualizada (desde 2008). Por favor, use 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).
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:
>set PYTHONIOENCODING=UTF-8
Como la respuesta de Giampaolo Rodolà, pero aún más sucia: realmente, realmente pretendo pasar mucho tiempo (pronto) comprendiendo todo el tema de las codificaciones y cómo se aplican a las consolas Windoze.
Por el momento solo quería algo, lo que significaría que mi programa NO CRUCARÍA, y que entendí ... y también que no implicaba importar demasiados módulos exóticos (en particular, estoy usando Jython, así que la mitad de las veces un Python). El módulo resulta que, de hecho, no está disponible).
def pr(s):
try:
print(s)
except UnicodeEncodeError:
for c in s:
try:
print( c, end='''')
except UnicodeEncodeError:
print( ''?'', end='''')
NB: "pr" es más corto de escribir que "imprimir" (y un poco más corto de escribir que "safeprint") ...!
El siguiente código hará que la salida de Python se consiga 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ás redirigir la salida a un archivo.
A continuación se probó el código con Python 2.6 en Windows.
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import codecs, sys
reload(sys)
sys.setdefaultencoding(''utf-8'')
print sys.getdefaultencoding()
if sys.platform == ''win32'':
try:
import win32console
except:
print "Python Win32 Extensions module is required./n You can download it from https://sourceforge.net/projects/pywin32/ (x86 and x64 builds are available)/n"
exit(-1)
# win32console implementation of SetConsoleCP does not return a value
# CP_UTF8 = 65001
win32console.SetConsoleCP(65001)
if (win32console.GetConsoleCP() != 65001):
raise Exception ("Cannot set console codepage to 65001 (UTF-8)")
win32console.SetConsoleOutputCP(65001)
if (win32console.GetConsoleOutputCP() != 65001):
raise Exception ("Cannot set console output codepage to 65001 (UTF-8)")
#import sys, codecs
sys.stdout = codecs.getwriter(''utf8'')(sys.stdout)
sys.stderr = codecs.getwriter(''utf8'')(sys.stderr)
print "This is an Е乂αmp١ȅ testing Unicode support using Arabic, Latin, Cyrillic, Greek, Hebrew and CJK code points./n"
James Sulak preguntó,
¿Hay alguna manera de hacer que Python imprima automáticamente un? En lugar de fallar en esta situación?
Otras soluciones recomiendan que intentemos modificar el entorno de Windows o reemplazar la función
print()
Python.
La respuesta a continuación se acerca al cumplimiento de la solicitud de Sulak.
Bajo Windows 7, Python 3.5 se puede hacer para imprimir Unicode sin lanzar un
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 noir
En lugar de
Halmalo n''était plus qu''un point noir
Por supuesto, el último es preferible ceteris paribus , pero de lo contrario el primero es completamente exacto 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
llamada
str()
anterior es necesaria porque de lo contrario,
encode()
hace que Python rechace un carácter Unicode como una tupla de números.
La causa de su problema NO es que la consola Win no esté dispuesta a aceptar Unicode (ya que lo hace ya que supongo que Win2k por defecto). Es la codificación del sistema por defecto. Prueba este código y mira lo que te da:
import sys
sys.getdefaultencoding()
si dice ascii, 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:
import sys
sys.setdefaultencoding(''utf-8'')
y quizás también desee especificar la codificación en sus archivos:
# -*- coding: UTF-8 -*-
import sys,time
Edición: se puede encontrar más información en el excelente libro Dive into Python
Para Python 2 intente:
print unicode(string, ''unicode-escape'')
Para Python 3 intente:
import os
string = "002 Could''ve Would''ve Should''ve"
os.system(''echo '' + string)
O prueba win-unicode-console:
pip install win-unicode-console
py -mrun your_script.py
Python 3.6 windows7: hay varias formas de iniciar 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. Imprimiendo caracteres utf-8 me lanza este error:
OSError: [winError 87] The paraneter is incorrect
Exception ignored in: (_io-TextIOwrapper name=''(stdout)'' mode=''w'' '' encoding=''utf8'')
OSError: [WinError 87] The parameter is incorrect
Después de intentar y no entender la respuesta anterior, descubrí que era solo un problema de configuración.
Haga clic con el botón derecho en la parte superior de las ventanas de la consola cmd, en la
font
la pestaña, seleccione lucida console.
Si no estás interesado en obtener una representación confiable de los caracteres incorrectos, puedes usar algo como esto (trabajar con python> = 2.6, incluido 3.x):
from __future__ import print_function
import sys
def safeprint(s):
try:
print(s)
except UnicodeEncodeError:
if sys.version_info >= (3,):
print(s.encode(''utf8'').decode(sys.stdout.encoding))
else:
print(s.encode(''utf8''))
safeprint(u"/N{EM DASH}")
Los caracteres incorrectos en la cadena se convertirán en una representación que puede imprimir la consola de Windows.
Simplemente ingrese este código en la línea de comandos antes de ejecutar el script de Python:
chcp 65001 & set PYTHONIOENCODING=utf-8
TL; DR:
print(yourstring.encode(''ascii'',''replace''));
Me encontré con esto, trabajando en un bot de Twitch chat (IRC). (Python 2.7 más reciente)
Quería analizar los mensajes de chat para responder ...
msg = s.recv(1024).decode("utf-8")
pero también imprímalos de forma segura en la consola en un formato legible por humanos:
print(msg.encode(''ascii'',''replace''));
Esto corrigió el problema del bot lanzando
UnicodeEncodeError: ''charmap''
errores
UnicodeEncodeError: ''charmap''
y reemplazó los caracteres Unicode con
?
.
Actualización:
Python 3.6
implementa
PEP 528: Cambia 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 de Unicode que
el paquete
win-unicode-console
que se menciona a continuación
.
print(unicode_string)
debería funcionar ahora.
Obtengo un
UnicodeEncodeError: ''charmap'' codec can''t encode character...
error.
El error significa que los caracteres Unicode que intenta imprimir no se pueden representar mediante la codificación de caracteres de la consola actual (
chcp
).
La página de códigos suele ser una codificación de 8 bits, como
cp437
que puede representar solo ~ 0x100 caracteres de ~ 1M caracteres Unicode:
>>> u"/N{EURO SIGN}".encode(''cp437'') Traceback (most recent call last): ... UnicodeEncodeError: ''charmap'' codec can''t encode character ''/u20ac'' in position 0: character maps to
Supongo que esto se debe a que la consola de Windows no acepta caracteres solo de Unicode. ¿Cuál es la mejor manera de evitar esto?
La consola de Windows acepta caracteres Unicode e incluso puede mostrarlos (solo BMP)
si la fuente correspondiente está configurada
.
WriteConsoleW()
API de
WriteConsoleW()
debe usarse como se sugiere en
la respuesta de @Daira Hopwood
.
Puede llamarse de forma transparente, es decir, no necesita y no debe modificar sus scripts si utiliza el
paquete
win-unicode-console
:
T:/> py -mpip install win-unicode-console
T:/> py -mrun your_script.py
Consulte ¿Cuál es el problema con Python 3.4, Unicode, diferentes idiomas y Windows?
¿Hay alguna manera de hacer que Python imprima automáticamente un
?
En lugar de fallar en esta situación?
Si es suficiente para reemplazar todos los caracteres no codificables con
?
En su caso, entonces podría establecer
PYTHONIOENCODING
PYTHONIOENCODING
:
T:/> set PYTHONIOENCODING=:replace
T:/> python3 -c "print(u''[/N{EURO SIGN}]'')"
[?]
En Python 3.6+, la codificación especificada por el
PYTHONIOENCODING
PYTHONIOENCODING se ignora para los buffers de la consola interactiva a menos que el
PYTHONLEGACYWINDOWSIOENCODING
PYTHONLEGACYWINDOWSIOENCODING esté establecido en una cadena no vacía.
Nota: Esta respuesta está desactualizada (de 2008). Por favor, use la solución a continuación con cuidado!
Aquí hay una página que detalla el problema y una solución (busque el texto Wrapping sys.stdout en una instancia ):
Aquí hay un extracto de código de esa página:
$ python -c ''import sys, codecs, locale; print sys.stdout.encoding; /
sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout); /
line = u"/u0411/n"; print type(line), len(line); /
sys.stdout.write(line); print line''
UTF-8
<type ''unicode''> 2
Б
Б
$ python -c ''import sys, codecs, locale; print sys.stdout.encoding; /
sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout); /
line = u"/u0411/n"; print type(line), len(line); /
sys.stdout.write(line); print line'' | cat
None
<type ''unicode''> 2
Б
Б
Hay más información en esa página, vale la pena leerla.