Estoy luchando con la conversión de impresión y Unicode. Aquí hay algún código ejecutado en el intérprete de Windows 2.5.Imprimir objetos y unicode, ¿qué hay debajo del capó? ¿Cuáles son las buenas pautas?
>>> import sys
>>> print sys.stdout.encoding
cp850
>>> print u"é"
é
>>> print u"é".encode("cp850")
é
>>> print u"é".encode("utf8")
├®
>>> print u"é".__repr__()
u'\xe9'
>>> class A():
... def __unicode__(self):
... return u"é"
...
>>> print A()
<__main__.A instance at 0x0000000002AEEA88>
>>> class B():
... def __repr__(self):
... return u"é".encode("cp850")
...
>>> print B()
é
>>> class C():
... def __repr__(self):
... return u"é".encode("utf8")
...
>>> print C()
├®
>>> class D():
... def __str__(self):
... return u"é"
...
>>> print D()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 0: ordinal not in range(128)
>>> class E():
... def __repr__(self):
... return u"é"
...
>>> print E()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 0: ordinal not in range(128)
lo tanto, cuando se imprime una cadena Unicode, no es que es __repr__()
función que se llama y se imprime.
Pero cuando se imprime un objeto o __str__()
__repr__()
(si __str__
no implementado) se llama, no __unicode__()
. Ambos no pueden devolver una cadena Unicode.
¿Pero por qué? ¿Por qué si __repr__()
o __str__()
devuelven una cadena Unicode, ¿no debería ser el mismo comportamiento que cuando imprimimos una cadena Unicode? En otras palabras: ¿por qué print D()
es diferente de print D().__str__()
¿E-candole algo?
Estas muestras también muestran que si desea imprimir un objeto representado con cadenas Unicode, hay que codificar a una cadena de objetos (tipo str). Pero para una buena impresión (evite el "├®"), depende de la codificación sys.stdout
.
Por lo tanto, tengo que añadir u"é".encode(sys.stdout.encoding)
para cada uno de mi método __str__
o __repr__
? ¿O devolver repr (u "é")? ¿Qué sucede si uso tuberías? ¿Es la misma codificación que sys.stdout
?
Mi problema principal es hacer una clase de "imprimir", es decir print A()
imprime algo totalmente legible (no con los \ x *** caracteres Unicode). Aquí es el mal comportamiento/código que necesita ser modificado:
class User(object):
name = u"Luiz Inácio Lula da Silva"
def __repr__(self):
# returns unicode
return "<User: %s>" % self.name
# won't display gracefully
# expl: print repr(u'é') -> u'\xe9'
return repr("<User: %s>" % self.name)
# won't display gracefully
# expl: print u"é".encode("utf8") -> print '\xc3\xa9' -> ├®
return ("<User: %s>" % self.name).encode("utf8")
Gracias!
Gracias Alex, ahora veo por qué 'D de impresión()' tiene un comportamiento diferente de 'impresión D() .__ str __()'. Fue un poco confuso Entonces, ¿podría compartir alguna guía cuando necesite manejar cadenas unicode en los métodos __repr__ o __str__? ¿Debo devolver un repr() de todo el Unicode o codificarlo en un objeto de cadena? O aún podría devolver un código unicode y establecer la codificación con sys.setdefaultencoding en un módulo de sitio personalizado (pero me pareció demasiado intrusivo). – Thorfin
@Thorfin, para devolver Unicode, implemente '__unicode__'. '__str__' siempre debe devolver una cadena de bytes, y' __repr__' una cadena de bytes que "idealmente" (pero eso no siempre es posible o razonable) uno podría 'eval' para construir un nuevo objeto. –
Creo que '__unicode__' solo se llama junto con unicode(), y desafortunadamente eso no soluciona mis problemas. He agregado información al final del cuerpo de mi pregunta inicial. Gracias de nuevo. – Thorfin