utf8 type chinese python encoding ascii repr

python - type - ¿El mejor tipo de salida y prácticas de codificación para las funciones__repr__()?



python encoding ansi (3)

Últimamente, he tenido muchos problemas con __repr__() , format() y codificaciones. ¿Debería codificarse la salida de __repr__() o ser una cadena unicode? ¿Hay una mejor codificación para el resultado de __repr__() en Python? Lo que quiero mostrar tiene caracteres que no sean ASCII.

Uso Python 2.x y quiero escribir código que se pueda adaptar fácilmente a Python 3. El programa utiliza

# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function # The ''Hello'' literal represents a Unicode object

Aquí hay algunos problemas adicionales que me han estado molestando, y estoy buscando una solución que los resuelva:

  1. La impresión en un terminal UTF-8 debería funcionar (he sys.stdout.encoding configurado en UTF-8 , pero sería mejor si otros casos funcionaran también).
  2. Tubería de salida a un archivo (codificado en UTF-8) debería funcionar (en este caso, sys.stdout.encoding es None ).
  3. Mi código para muchas __repr__() actualmente tiene muchos return ….encode(''utf-8'') , y eso es pesado. ¿Hay algo robusto y ligero?
  4. En algunos casos, incluso tengo bestias feas como el return (''<{}>''.format(repr(x).decode(''utf-8''))).encode(''utf-8'') , es decir, la representación de objetos se decodifica, se pone en una cadena de formato y luego se vuelve a codificar. Me gustaría evitar tales transformaciones enrevesadas.

¿Qué recomendarías hacer para escribir __repr__() simples __repr__() que se comporten bien con respecto a estas preguntas de codificación?


Creo que un decorador puede manejar incompatibilidades __repr__ de una manera __repr__ . Esto es lo que uso:

from __future__ import unicode_literals, print_function import sys def force_encoded_string_output(func): if sys.version_info.major < 3: def _func(*args, **kwargs): return func(*args, **kwargs).encode(sys.stdout.encoding or ''utf-8'') return _func else: return func class MyDummyClass(object): @force_encoded_string_output def __repr__(self): return ''My Dummy Class! /N{WHITE SMILING FACE}''


En Python2, __repr__ (y __str__ ) debe devolver un objeto de cadena, no un objeto Unicode. En Python3, la situación se invierte, __repr__ y __str__ deben devolver objetos unicode, no objetos de byte (cadena née):

class Foo(object): def __repr__(self): return u''/N{WHITE SMILING FACE}'' class Bar(object): def __repr__(self): return u''/N{WHITE SMILING FACE}''.encode(''utf8'') repr(Bar()) # ☺ repr(Foo()) # UnicodeEncodeError: ''ascii'' codec can''t encode character u''/u263a'' in position 0: ordinal not in range(128)

En Python2, realmente no tienes otra opción. Debes elegir una codificación para el valor de retorno de __repr__ .

Por cierto, ¿has leído el wiki PrintFails ? Es posible que no responda directamente sus otras preguntas, pero lo encontré útil para esclarecer por qué ocurren ciertos errores.

Al usar from __future__ import unicode_literals ,

''<{}>''.format(repr(x).decode(''utf-8''))).encode(''utf-8'')

puede ser escrito más simplemente como

str(''<{}>'').format(repr(x))

asumiendo que str codifica a utf-8 en su sistema.

Sin from __future__ import unicode_literals , la expresión se puede escribir como:

''<{}>''.format(repr(x))


Yo uso una función como la siguiente:

def stdout_encode(u, default=''UTF8''): if sys.stdout.encoding: return u.encode(sys.stdout.encoding) return u.encode(default)

Entonces mis funciones __repr__ ven así:

def __repr__(self): return stdout_encode(u''<MyClass {0} {1}>''.format(self.abcd, self.efgh))