¿Cuál es el problema con Python 3.4, Unicode, diferentes idiomas y Windows?

Felices ejemplos:

#!/usr/bin/env python # -*- coding: utf-8 -*- czech = u'Leoš Janáček'.encode("utf-8") print(czech) pl = u'Zdzisław Beksiński'.encode("utf-8") print(pl) jp = u'リング 山村 貞子'.encode("utf-8") print(jp) chinese = u'五行'.encode("utf-8") print(chinese) MIR = u'Машина для Инженерных Расчётов'.encode("utf-8") print(MIR) pt = u'Minha Língua Portuguesa: çáà'.encode("utf-8") print(pt) 

Salida infeliz:

 b'Leo\xc5\xa1 Jan\xc3\xa1\xc4\x8dek' b'Zdzis\xc5\x82aw Beksi\xc5\x84ski' b'\xe3\x83\xaa\xe3\x83\xb3\xe3\x82\xb0 \xe5\xb1\xb1\xe6\x9d\x91 \xe8\xb2\x9e\xe5\xad\x90' b'\xe4\xba\x94\xe8\xa1\x8c' b'\xd0\x9c\xd0\xb0\xd1\x88\xd0\xb8\xd0\xbd\xd0\xb0 \xd0\xb4\xd0\xbb\xd1\x8f \xd0\x98\xd0\xbd\xd0\xb6\xd0\xb5\xd0\xbd\xd0\xb5\xd1\x80\xd0\xbd\xd1\x8b\xd1\x85 \xd0\xa0\xd0\xb0\xd1\x81\xd1\x87\xd1\x91\xd1\x82\xd0\xbe\xd0\xb2' b'Minha L\xc3\xadngua Portuguesa: \xc3\xa7\xc3\xa1\xc3\xa0' 

Y si los imprimo así:

 jp = u'リング 山村 貞子' print(jp) 

Yo obtengo:

 Traceback (most recent call last): File "x.py", line 5, in  print(jp) File "C:\Python34\lib\encodings\cp850.py", line 19, in encode return codecs.charmap_encode(input,self.errors,encoding_map)[0] UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-2: character maps to  

También he intentado lo siguiente de esta pregunta (y otras alternativas que involucran a sys.stdout.encoding ):

 #!/usr/bin/env python # -*- coding: utf-8 -*- 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')) jp = u'リング 山村 貞子' safeprint(jp) 

Y las cosas se ponen aún más crípticas:

 リング 山村 貞子 

Y los documentos no fueron de mucha ayuda .

Entonces, ¿cuál es el problema con Python 3.4, Unicode, diferentes idiomas y Windows? Casi todos los ejemplos posibles que pude encontrar, tratan con Python 2.x.

¿Existe una forma general y multiplataforma de imprimir CUALQUIER personaje Unicode desde cualquier idioma de una manera decente y no desagradable en Python 3.4?

EDITAR:

He intentado escribir en la terminal:

 chcp 65001 

Para cambiar la página de códigos, como se propone aquí y en los comentarios, y no funcionó (incluido el bash con sys.stdout.encoding)

El problema fue que (consulte la actualización de Python 3.6 a continuación) con la consola de Windows, que admite un conjunto de caracteres ANSI adecuado para la región a la que se dirige su versión de Windows. Python lanza una excepción de forma predeterminada cuando se generan caracteres no compatibles.

Python puede leer una variable de entorno para generar en otras codificaciones, o para cambiar el valor predeterminado de manejo de errores. A continuación, he leído la configuración predeterminada de la consola y he cambiado la gestión de errores predeterminada para imprimir una ? en lugar de lanzar un error para los caracteres que no se admiten en la página de códigos actual de la consola.

 C:\>chcp Active code page: 437 # Note, US Windows OEM code page. C:\>set PYTHONIOENCODING=437:replace C:\>example.py Leo? Janá?ek Zdzis?aw Beksi?ski ??? ?? ?? ?? ?????? ??? ?????????? ???????? Minha Língua Portuguesa: çáà 

Tenga en cuenta que la página de códigos OEM de los EE. UU. Está limitada a ASCII y algunos caracteres de Europa occidental.

A continuación, le indiqué a Python que usara UTF8, pero como la consola de Windows no lo admite, redirijo la salida a un archivo y la muestro en el Bloc de notas:

 C:\>set PYTHONIOENCODING=utf8 C:\>example >out.txt C:\>notepad out.txt 

introduzca la descripción de la imagen aquí

En Windows, es mejor usar un IDE de Python que sea compatible con UTF-8 en lugar de la consola cuando se trabaja con varios idiomas. Si solo usa un idioma, selecciónelo como la configuración regional del sistema en el panel de control de Region and Language y la consola admitirá los caracteres de ese idioma.

Actualización para Python 3.6

Python 3.6 ahora usa las API de Windows Unicode para escribir directamente en la consola, por lo que el único límite es el soporte de los caracteres por parte de la consola. El siguiente código funciona en una consola de Windows de Estados Unidos. Tengo un paquete de idioma chino instalado, incluso muestra el chino y el japonés si se cambia la fuente de la consola. Incluso sin la fuente correcta, los caracteres de reemplazo se muestran en la consola. Cortar y pegar en un entorno como esta página web mostrará los caracteres correctamente.

 #!python3.6 #coding: utf8 czech = 'Leoš Janáček' print(czech) pl = 'Zdzisław Beksiński' print(pl) jp = 'リング 山村 貞子' print(jp) chinese = '五行' print(chinese) MIR = 'Машина для Инженерных Расчётов' print(MIR) pt = 'Minha Língua Portuguesa: çáà' print(pt) 

Salida:

 Leoš Janáček Zdzisław Beksińskiリング 山村 貞子五行Машина для Инженерных Расчётов Minha Língua Portuguesa: çáà 

Actualización: Desde Python 3.6, el ejemplo de código que imprime cadenas de Unicode directamente debería funcionar ahora (incluso sin py -mrun ) .


Python puede imprimir texto en varios idiomas en la consola de Windows, lo que diga chcp :

 T:\> py -mpip install win-unicode-console T:\> py -mrun your_script.py 

donde your_script.py imprime Unicode directamente, por ejemplo:

 #!/usr/bin/env python3 print('š áč') # cz print('ł ń') # pl print('リング') # jp print('五行') # cn print('ш я жх ё') # ru print('í çáà') # pt 

Todo lo que necesita es configurar la fuente en su consola de Windows que pueda mostrar los caracteres deseados.

También puede ejecutar su script de Python a través de IDLE sin instalar módulos que no sean stdlib:

 T:\> py -midlelib -r your_script.py 

Para escribir en un archivo / tubería, use PYTHONIOENCODING=utf-8 como @Mark Tolonen sugirió :

 T:\> set PYTHONIOENCODING=utf-8 T:\> py your_script.py >output-utf8.txt 

Solo la última solución admite caracteres no BMP como such (U + 1F612 UNAMUSED FACE) – py -mrun puede escribirlos, pero la consola de Windows los muestra como cuadros incluso si la fuente admite los caracteres Unicode correspondientes (aunque puede copiar y pegar los caracteres). cajas en otro progtwig, para obtener los personajes).