¿Por qué python 2.7 en Windows necesita un espacio antes del carácter Unicode cuando se imprime?

Yo uso cmd Windows, chcp 65001, este es mi código:

print u'\u0110 \u0110' + '\n' 

Resultado:

  (a character cmd can't display) (character what i want) Traceback (most recent call last): File "b.py", line 26, in  print u'\u0110 \u0110' IOError: [Errno 2] No such file or directory 

Pero, cuando uso este código:

 print u' \u0110 \u0110' + '\n' 

Resultado:

 (a space)(charecter what i want) (character what i want) Traceback (most recent call last): File "b.py", line 26, in  print u' \u0110 \u0110' + '\n' IOError: [Errno 2] No such file or directory 

Mi pantalla introduzca la descripción de la imagen aquí

Y mi pregunta es:

  • ¿Por qué Python 2.7 necesita un espacio al imprimir un carácter Unicode?

  • Cómo arreglar IOError: [Errno 2]

Respuesta corta

En Windows no puede imprimir cadenas arbitrarias utilizando print .

Hay algunas soluciones alternativas, como se muestra aquí: Cómo hacer python 3 print () utf8 . Pero, a pesar del título de esa pregunta, no puede usar esto para imprimir realmente UTF-8 usando la página de códigos 65001, se repetirán los últimos bytes después de terminar (como lo describí más abajo)

ejemplo:

 #! python2 import sys enc = sys.stdout.encoding def outputUnicode(t): bytes = t.encode(enc, 'replace') sys.stdout.write(bytes) outputUnicode(u'The letter \u0110\n') 

Respuesta larga

Puede cambiar la página de códigos de la consola usando chcp a una página de códigos que contenga los caracteres que desea imprimir. En su caso, por ejemplo, ejecute chcp 852 .

Estos son los resultados en mi caja si imprimo las siguientes cadenas. Estoy usando la página de códigos 850, que es la predeterminada para los sistemas en inglés:

 u"\u00abHello\u00bb" # "«Hello»" u"\u0110" # "Đ" u"\u4f60\u597d" # "你好" u"a\u2192b\u2192c" # "a→b→c" 

El primer comando funcionará, ya que todos los caracteres están en la página de códigos 850. Los siguientes 3 fallarán.

UnicodeEncodeError: 'charmap' codec can't encode character u'\u0110' in position 0: character maps to

Cambie la página de códigos a 852 y el segundo comando funcionará.

Hay una página de códigos UTF-8 (65001) pero no funciona con Python 2.7.

En Python 3.4 los resultados son los mismos. Si cambias la página de códigos a 65001, obtendrás un comportamiento menos roto.

\Python34\python.exe -c "print(u'a\u2192b\u2192c')" a→b→c c C:\>

Los dos caracteres adicionales ( c) son una consecuencia del comportamiento no estándar en la biblioteca estándar de C en Windows. Son una repetición de los últimos 2 bytes en la encoding UTF-8 de la cadena.

En Windows puede imprimir cadenas arbitrarias utilizando la print (siempre que la fuente pueda mostrar los caracteres). Solo print Unicode y configura tu entorno.

Por ejemplo, print_unicode.py :

 #!/usr/bin/env python print(u'\u0110\u0110') 

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

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

No te olvides de configurar la fuente de consola adecuada. chcp valor de retorno de chcp no importa en este caso.

Puede llamar a la función WriteConsoleW() (Unicode API) manualmente , para imprimir texto arbitrario en la consola de Windows.

No necesita módulos de terceros para redirigir la salida a un archivo:

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

Nota: el módulo de run no se utiliza. Funciona tanto en Python 2 como en 3.

Si no necesita imprimir caracteres Unicode que no sean BMP, entonces podría usar Python IDLE desde stdlib, por ejemplo, en Python 3:

 T:\> py -3 -midlelib -r print_unicode.py 

IDLE también está disponible en Python 2, pero la invocación es diferente.