Ошибка юникода Python

Может кто-нибудь объяснить мне, почему в приведенном ниже примере print a вызывает исключение, а a.__str__() нет?

>>> class A:
...   def __init__(self):
...     self.t1 = "čakovec".decode("utf-8")
...     self.t2 = "tg"
...   def __str__(self):
...     return self.t1 + self.t2
... 
>>> a = A()
>>> print a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u010d' in position 0: ordinal not in range(128)
>>> a.__str__()
u'\u010dakovectg'
>>> print a.__str__()
čakovectg

person user1267132    schedule 30.08.2013    source источник


Ответы (1)


В Python 2 str должен возвращать строку ASCII. Когда вы вызываете __str__ напрямую, вы пропускаете этап преобразования Python вывода __str__ в строку ASCII (на самом деле вы можете вернуть все, что хотите, из __str__, но не должны). __str__ не должен возвращать объект unicode, он должен возвращать объект str.

Вот что вы можете сделать вместо этого:

In [29]: class A(object):
    ...:     def __init__(self):
    ...:         self.t1 = u"c∃".encode('utf8')
    ...:     def __str__(self):
    ...:         return self.t1
    ...:     

In [30]: a = A()

In [31]: print a
c∃

In [32]: str(a)
Out[32]: 'c\xe2\x88\x83'

In [33]: a.__str__()
Out[33]: 'c\xe2\x88\x83'
person Phillip Cloud    schedule 30.08.2013