0

I have a class SomeClass, I want to print this class while debugging:

def __repr__(self):
    print type(self.id)
    print type(self.cn_name)
    print type(self.name)
    print type(self.finished)
    return u'''
    Bangumi id: %s
    Chinese Name: %s
    Original Name: %s
    Finished or Not: %s''' % (self.id, self.cn_name, self.name, self.finished)

I get these information below:

>>> print anime.__repr__
<type 'int'>
<type 'unicode'>
<type 'unicode'>
<type 'int'>
Traceback (most recent call last):

File "<debugger>", line 1, in <module>
print anime.__repr__
UnicodeEncodeError: 'ascii' codec can't encode characters in position 45-50: ordinal not in range(128)

What does this mean? How should I recover it?

Kane Blueriver
  • 4,170
  • 4
  • 29
  • 48
  • Your `__repr__` method correctly returned a Unicode string, but your console or terminal is not correctly configured and Python tried to encode the result to ASCII. – Martijn Pieters Mar 26 '14 at 15:02
  • What terminal or console are you using? Note that some IDE consoles do not correctly tell Python what encoding to use. – Martijn Pieters Mar 26 '14 at 15:04
  • Note that you **should never return Unicode from `__repr__`**; everything else in Python 2 always returns bytestrings, see the [`__repr__` documentation](http://docs.python.org/2/reference/datamodel.html#object.__repr__). This is a separate issue; your console won't print any other unicode either. – Martijn Pieters Mar 26 '14 at 15:12
  • @MartijnPieters I'm using PyCharmCE, the newest version. Is that the point? – Kane Blueriver Mar 27 '14 at 00:44
  • @MartijnPieters It's also wrong in terminal.(I am using OS X 10.9, and the language is Chinese) – Kane Blueriver Mar 27 '14 at 00:54
  • I'll see tomorrow when on my laptop again; most likely Python is encoding the `__repr__` return value because Python *expects a byte string* from that method. Can you print the same text directly outside of the method? – Martijn Pieters Mar 27 '14 at 00:58
  • I checked the Python source code instead; `repr()` does encode the `__repr__` return value, and your `anime.__repr__` triggers that by not actually calling the method. – Martijn Pieters Mar 27 '14 at 01:29
  • @MartijnPieters Manual print is OK. After reading your suggest, I added an encode function before return, then it fixed. BTW, while using flask_whooshalchemy.whoosh_search(), I got the same error, that confused me. But finally I found it's because whoosh_search need a Unicode value meanwhile I passed a str while testing. – Kane Blueriver Mar 27 '14 at 02:57
  • Str and Unicode are really headache part of Python 2! – Kane Blueriver Mar 27 '14 at 02:58

1 Answers1

1

The __repr__ method must return a byte string object; a str. You are returning a unicode object instead, and Python encodes it implicitly, using the ASCII codec, to force it to a string.

Incidentally, this would not happen if you actually called anime.__repr__(); instead you are just referring to the method object, whose representation includes a repr(anime) string, and it's the repr() function that does the encoding.

You can fix this by not returning Unicode from the method. Encode the return value to str explicitly.

Add a __unicode__ method to create a Unicode string instead. See Python __str__ versus __unicode__

Community
  • 1
  • 1
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343