2010-09-18 35 views
6

Cuando intento imprimir una cadena Unicode en mi servidor de desarrollo, funciona correctamente, pero el servidor de producción genera una excepción.La impresión de Python funciona de manera diferente en servidores diferentes

File "/home/user/twistedapp/server.py", line 97, in stringReceived 
    print "sent:" + json 
File "/usr/lib/python2.6/dist-packages/twisted/python/log.py", line 555, in write 
    d = (self.buf + data).split('\n') 
exceptions.UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 28: ordinal not in range(128) 

En realidad es una aplicación retorcida e imprime hacia adelante en el archivo de registro.

repr() de cadenas son las mismas. Configuración regional configurada en en_US.UTF-8.

¿Hay alguna configuración que deba verificar para que funcione igual en ambos servidores?

+1

¿Qué versiones de OS y Python están ejecutando los servidores? – Puddingfox

+0

Ubuntu 10.04 Server ambos – Soid

+0

y Python 2.6.5 – Soid

Respuesta

1

Unicode no es compatible con los observadores de registro integrados de Twisted. Consulte http://twistedmatrix.com/trac/ticket/989 para obtener información sobre cómo agregar soporte para esto o para ver qué puede hacer para ayudar.

Hasta que se resuelva el # 989 y la solución esté en una versión Twisted en la que se implementa su aplicación, no inicie sesión en unicode. Solo registro str.

+0

¿por qué puede funcionar de manera diferente en los diferentes servidores? – Soid

+0

Estaría bien si tuviera que codificar o decodificar o algo así. Pero el servidor de producción necesita hacer una decodificación ('utf8') y el servidor de desarrollo no permite hacerlo. – Soid

7

print ción de cadenas Unicode se basa en sys.stdout (salida estándar del proceso) que tiene una .encoding atributo correcto que Python se puede utilizar para codificar la cadena Unicode en una cadena de bytes para realizar la impresión requerida - y que ajuste depende de la forma el sistema operativo está configurado, a donde se dirige la salida estándar, y así sucesivamente.

Si no hay tal atributo, se utiliza el código predeterminado ascii, y, como ha visto, a menudo no proporciona los resultados deseados ;-).

Puede consultar getattr(sys.stdout, 'encoding', None) para ver si la codificación está allí (si es así, puede cruzar los dedos para asegurarse de que sea correcta ... o, tal vez, pruebe un truco específico de plataforma para adivinar el sistema correcto codificación para verificar ;-). Si no es así, en general, no hay una manera confiable o multiplataforma de adivinar cuál podría ser. Usted podría intente 'utf8', la codificación universal que funciona en muchos casos (seguramente más que ascii ;-), pero es realmente un giro de la rueda de la ruleta.

Para mayor confiabilidad, su programa debe tener su propio archivo de configuración para indicarle qué codificación de salida usar (tal vez con 'utf8' como el predeterminado si no se especifica lo contrario).

También es mejor, para la portabilidad, para llevar a cabo su propia codificación, es decir, no

print someunicode 

sino

print someunicode.encode(thecodec) 

y, de hecho, si usted prefiere tener producción incompleta que un bloqueo,

print someunicode.encode(thecodec, 'ignore') 

(que simplemente omite n en codificable caracteres), o, por lo general mejor,

print someunicode.encode(thecodec, 'replace') 

(que utiliza marcadores de posición de la pregunta-marca de caracteres que no son codificables).

+2

Creo que vale la pena mencionar que en sistemas UNIX, sys.stdout.la codificación se establece en base a las variables de entorno 'LANG',' LC_ALL' y 'LC_CTYPE', y que está * solo * establecido si sys.stdout está conectado a un terminal. Las mismas impresiones de trabajo pueden por desgracia romperse cuando redirige la salida a un archivo u otro programa. Esto hace que sea aún más importante codificar explícitamente su Unicode. –

+0

@Thomas, sí, absolutamente, excelente punto! –

+0

No funciona, causa salidas de impresión a los registros. Actualicé mi pregunta Gracias por su respuesta. Configuración regional establecida en en_US.UTF-8 en ambos servidores. – Soid

Cuestiones relacionadas