Sono alle prese con la conversione di stampa e unicode. Ecco un codice eseguito nell'interprete di Windows 2.5.Stampa di oggetti e unicode, cosa c'è sotto il cofano? Quali sono le buone linee guida?
>>> 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)
Così, quando una stringa unicode viene stampato, non è che sia __repr__()
funzione che si chiama e stampata.
Tuttavia, quando viene stampato un oggetto, viene chiamato __str__()
o __repr__()
(se __str__
non è implementato), non __unicode__()
. Entrambi non possono restituire una stringa Unicode.
Ma perché? Perché se __repr__()
o __str__()
restituisce una stringa unicode, non dovrebbe essere lo stesso comportamento di quando stampiamo una stringa Unicode? Ho altre parole: perché print D()
è diverso da print D().__str__()
Mi manca qualcosa?
Questi esempi mostrano anche che se si desidera stampare un oggetto rappresentato con stringhe Unicode, è necessario codificarlo su una stringa di oggetto (tipo str). Ma per una buona stampa (evita "├®"), dipende dalla codifica sys.stdout
.
Quindi, devo aggiungere u"é".encode(sys.stdout.encoding)
per ciascuno dei miei metodi __str__
o __repr__
? Oppure restituisci repr (u "é")? Cosa succede se utilizzo le tubazioni? La codifica è la stessa di sys.stdout
?
Il mio problema principale è rendere una classe "stampabile", ovvero print A()
stampa qualcosa completamente leggibile (non con i caratteri unicode di \ x ***). Qui è il comportamento/code male che deve essere modificato:
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")
Grazie!
Grazie Alex, ora vedo perché 'print D()' ha un comportamento diverso da 'print D() .__ str __()'. E 'stato un po' di confusione. Quindi, potresti condividere le linee guida quando devi gestire stringhe unicode nei metodi __repr__ o __str__? Dovrei restituire un repr() dell'intero unicode o codificarlo su un oggetto stringa? Oppure potrei ancora restituire un unicode e impostare la codifica con sys.setdefaultencoding in un modulo del sito personalizzato (ma ho trovato che questo è troppo invadente). – Thorfin
@Thorfin, per restituire Unicode, implementare '__unicode__'. '__str__' dovrebbe sempre restituire una stringa di byte, e' __repr__' una stringa di byte che "idealmente" (ma non è sempre possibile o ragionevole) si potrebbe 'eval' costruire un nuovo oggetto. –
Credo che "__unicode__" sia chiamato solo in congiunzione con unicode(), e sfortunatamente questo non risolve i miei problemi. Ho aggiunto alcune informazioni alla fine del corpo della mia domanda iniziale. Grazie ancora. – Thorfin