Imprima la cadena Unicode para consolar, pero falla cuando se redirige a un archivo. ¿Como arreglar?

Tengo Python 2.7.1 en una versión en chino simplificado de Windows XP, y tengo un progtwig como este (windows_prn_utf8.py):

#!/usr/bin/env python # -*- coding: utf8 -*- print unicode('\xE7\x94\xB5', 'utf8') 

Si lo ejecuto en la consola de Windows CMD, genera el carácter chino correcto ‘电’; sin embargo, si bash redirigir la salida del comando a un archivo. Tengo error

 D:\Temp>windows_prn_utf8.py > 1.txt Traceback (most recent call last): File "D:\Temp\windows_prn_utf8.py", line 4, in  print unicode('\xE7\x94\xB5', 'utf8') UnicodeEncodeError: 'ascii' codec can't encode character u'\u7535' in position 0: ordinal not in range(128) 

Me doy cuenta de que hay un eslabón perdido aquí. Debe haber una manera de determinar, en caso de que se genere 1.txt, si el carácter Unicode en 1.txt debe codificarse en utf-8 o en la página de códigos-936 u otras codificaciones.

Entonces, ¿cómo solucionarlo? Mi preferencia es tener la encoding utf-8 en 1.txt. Gracias.

introduzca la descripción de la imagen aquí

Establecer la variable ambiental PYTHONIOENCODING .

 SET PYTHONIOENCODING=cp936 windows_prn_utf8.py > 1.txt 

Parece que esto se resolvió, pero creo que un poco más de detalle ayudará a explicar este problema real.

El ‘utf8’ en unicode('\xE7\x94\xB5', 'utf8') le dice al intérprete cómo descodificar los 3 bytes que está proporcionando en el otro argumento para representar el carácter internamente como un objeto Unicode:

 In [6]: uobj = unicode('\xe7\x94\xb5','utf8') In [7]: uobj Out[7]: u'\u7535' 

Otro ejemplo sería crear el mismo carácter a partir de su representación utf-16 (que es lo que Python muestra de forma predeterminada y se muestra en la línea de Out[7] arriba):

 In [8]: uobj = unicode('\x35\x75','utf16') In [9]: uobj Out[9]: u'\u7535' 

En su ejemplo, una vez creado el objeto, se convierte en un argumento para print que intenta escribirlo en la salida estándar (ventana de la consola, redirigido a un archivo, etc.). La complicación es que la print debe volver a codificar ese objeto en un flujo de bytes antes de escribirlo. Parece que, en su caso, la encoding que usó por defecto fue ACSII, que no puede representar ese carácter.

(Si una consola intentará mostrar los caracteres, se volverán a descodificar y se reemplazarán en la ventana con los glifos de fuente correspondientes, por eso su salida y la consola deben “hablar” la misma encoding).

Por lo que he visto cmd.exe en Windows es bastante confuso cuando se trata de codificaciones de caracteres, pero lo que hago en otros sistemas operativos es codificar explícitamente los bytes antes de imprimirlos o escribirlos con la función de encode del objeto Unicode. Esto devuelve una secuencia de bytes codificada almacenada en un objeto str :

 In [10]: sobj = uobj.encode('utf8') In [11]: type(sobj) Out[11]: str In [12]: sobj Out[12]: '\xe7\x94\xb5' In [13]: print sobj电 

Ahora que a la print se le da un str lugar de un unicode , no necesita codificar nada. En mi caso, mi terminal estaba decodificando utf8, y su fuente contenía ese carácter particular, por lo que se mostraba correctamente en mi pantalla (y ahora mismo en su navegador).

Puede codificarlo en utf-8 antes de escribirlo en un archivo.

 f.write("电".encode("utf8")) 

Use codecs.open (nombre de archivo, encoding) en lugar de abrir (nombre de archivo) y escriba el archivo con python.