2011-08-16 10 views
6

DigamosPython 2.7: Salida de UTF-8 en la consola de Windows

s = u"test\u0627\u0644\u0644\u0647 \u0623\u0643\u0628\u0631\u7206\u767A\u043E\u043B\u043E\u043B\u043E" 

Si se intenta imprimir directamente,

>>> print s 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeEncodeError: 'cp932' codec can't encode character u'\u0627' in position 4: illegal multibyte sequence 

así que cambio la consola en UTF-8 desde el interior de Python (de lo contrario, no entenderá mi entrada).

import win32console 
win32console.SetConsoleOutputCP(65001) 
win32console.SetConsoleCP(65001) 

Y entonces la salida de la cadena codificada como UTF-8, ya que Python no sabe que chcp 65001 es UTF-8 (un conocido bug).

>>> print s.encode('utf-8') 
testالله أكبر爆発ололоTraceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
IOError: [Errno 0] Error 

Como se puede ver, se imprime con éxito hasta que se realiza un salto de línea, entonces es un error IOError.

La siguiente solución funciona:

def safe_print(str): 
    try: 
     print str.encode('utf-8') 
    except: 
     pass 
    print 

>>> safe_print(s) 
testالله أكبر爆発ололо 

Pero tiene que haber una mejor manera. ¿Alguna sugerencia?

+1

Espero que en realidad no llame al argumento 'str'. Evite sombrear builtins. –

+0

@Chris: ¿Cómo se supone que uno debe saber qué es lo que está incorporado y qué no? Es algo muy natural de hacer. ¿Cómo se puede garantizar un comportamiento limpio del espacio de nombres sin requerir conocimiento universal para comenzar? – tchrist

+0

En este caso, sin embargo, es potencialmente muy confuso, ya que el tipo 'str' tiene un método de codificación. – agf

Respuesta

1

No lo probé en Windows, pero here puede obtener una secuencia de comandos de inicialización pequeña para win/linux para configurar correctamente la codificación de salida, incluida la interfaz de registro, etc. El módulo también hace que la salida tenga color (incluida la actualización de 'registro ' interfaz)? pero puedes cortar fácilmente la funcionalidad innecesaria :-).

cómo invocar variante no coloreada:

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
from setupcon import setup_console 
setup_console('utf-8', False) 

y la variante de color:

import setupcon 
setupcon.setup_console() 
import logging 
#... 
if setupcon.ansi: 
    logging.getLogger().addHandler(setupcon.ColoredHandler()) 

Si la solución que funciona para usted, usted puede leer la documentación aquí: http://habrahabr.ru/blogs/python/117236/, en ruso, o yo/alguien puede traducirlo para usted a pedido :-).