2012-06-04 11 views
15

Esta pregunta se basa en un efecto secundario de that one.Imposible codificar/descodificar la salida de impresión

Mis .py archivos son todos tienen # -*- coding: utf-8 -*- codificación definidor en la primera línea, como mi api.py

Como menciono en la pregunta relacionada, yo uso HttpResponse para devolver la documentación de la API. Puesto que he definido codificación por:

HttpResponse(cy_content, content_type='text/plain; charset=utf-8') 

todo está bien, y cuando llamo a mi servicio API, no hay problemas de codificación excepto la cadena formada a partir de un diccionario por pprint

Desde que estoy usando turca personajes de algunos valores en mi dict, pprint los convierte en unichr equivalentes, como:

API_STATUS = { 
    1: 'müşteri', 
    2: 'some other status message' 
} 

my_str = 'Here is the documentation part that contains Turkish chars like işüğçö' 
my_str += pprint.pformat(API_STATUS, indent=4, width=1) 
return HttpRespopnse(my_str, content_type='text/plain; charset=utf-8') 

Y mi salida de texto sin formato es como:

Here is the documentation part that contains Turkish chars like işüğçö 

{ 
    1: 'm\xc3\xbc\xc5\x9fteri', 
    2: 'some other status message' 
} 

trato de descifrar o salida de codificación pprint a diferentes codificaciones, sin éxito ... ¿Cuál es la mejor práctica para superar este problema

Respuesta

35

pprint parece utilizar repr por defecto, se puede trabajar en torno a esta reemplazando PrettyPrinter.format:

# coding=utf8 

import pprint 

class MyPrettyPrinter(pprint.PrettyPrinter): 
    def format(self, object, context, maxlevels, level): 
     if isinstance(object, unicode): 
      return (object.encode('utf8'), True, False) 
     return pprint.PrettyPrinter.format(self, object, context, maxlevels, level) 


d = {'foo': u'işüğçö'} 

pprint.pprint(d)    # {'foo': u'i\u015f\xfc\u011f\xe7\xf6'} 
MyPrettyPrinter().pprint(d) # {'foo': işüğçö} 
+0

Gracias mucho, funciona como un amuleto (: – FallenAngel

+2

si, como yo, estás tratando de usar esto con 'pformat' (en lugar de pprint) y enviar la cadena resultante a un motor de plantillas como' jinja2', te dará un 'UnicodeDecodeError', que puede resolver llamando (en los términos de esta respuesta)' unicode (MyPrettyPrinter(). pformat (d), 'utf-8') '. – fiatjaf

+1

¿Puede envolver su pprint con la opción de configuración de formato para PyPI, será útil. –

1

Debe utilizar cadenas Unicode en lugar de los 8 bits:

API_STATUS = { 
    1: u'müşteri', 
    2: u'some other status message' 
} 

my_str = u'Here is the documentation part that contains Turkish chars like işüğçö' 
my_str += pprint.pformat(API_STATUS, indent=4, width=1) 

El módulo pprint está diseñada para imprimir todos los tipos posibles de estructura anidada de una manera legible. Para hacerlo, imprimirá la representación de los objetos en lugar de convertirla en una cadena, de modo que terminará con la sintaxis de escape cuando use cadenas de caracteres unicode o no. ¡Pero si está usando unicode en su documento, entonces realmente debería usar literales unicode!

De todos modos, thg435 has given you a solution cómo cambiar este comportamiento de pformat.

+0

son normales (no Unicode) cadenas conocidas como cadenas binarias? Pensé que eran ascii strings – jdi

+0

intenté eso también, también probé el 'smart_str',' smart_unicode' de django y otros métodos ... Cuando uso una cadena unicode como 'u'müşteri', lo que obtengo es' u'm \ xfc \ u015fteri'' – FallenAngel

+0

@FallenAngel - esa es la representación de la cadena Unicode que es generada por pformat, veo que su problema es un poco diferente de lo que pensaba ... Lo verificaré de nuevo ... – mata

Cuestiones relacionadas