Печать объектов и Unicode, что под капотом? Каковы хорошие рекомендации?

Я борюсь с печатью и преобразованием Юникода. Вот некоторый код, выполняемый в интерпретаторе 2.5 Windows.

>>> 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)

Итак, когда выводится строка Юникода, это не так __ repr __ () функция, которая вызывается и печатается.
Но когда объект печатается __str __ () или __ repr __ () (если __str __ не реализовано) вызывается, а не __ unicode __ () , Оба не могут возвращать строку Unicode.
Но почему? Почему, если __ repr __ () или __ str __ () возвращают строку в юникоде, разве это не должно быть таким же поведением, как при печати строки в юникоде? Другими словами: почему print D () отличается от print D () .__ str __ ()

Я что-то упустил?

Эти примеры также показывают, что если вы хотите напечатать объект, представленный строками Unicode, вы должны кодировать его в строку объекта (типа str). Но для хорошей печати (избегайте "├®"), это зависит от кодировки sys.stdout .
Итак, мне нужно добавить u "é" .encode (sys.stdout.encoding) для каждого из моих __ str __ или __ repr __ метод? Или вернуть repr (u "é")? Что если я использую трубопровод? Является ли эта кодировка такой же, как у sys.stdout ?

Моя главная проблема - сделать класс «пригодным для печати», т.е. print A () печатает что-то полностью читаемое (не с помощью \ x *** символы Юникода). Вот плохое поведение / код, который необходимо изменить:

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")

Спасибо!

6
задан Thorfin 24 August 2010 в 17:55
поделиться