我首先创建一个带有一些非 ascii utf-8编码数据的字符串变量:
>>> text = 'á'
>>> text
'\xc3\xa1'
>>> text.decode('utf-8')
u'\xe1'
使用unicode()
它会引发错误......
>>> unicode(text)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0:
ordinal not in range(128)
...但如果我知道编码,我可以将其用作第二个参数:
>>> unicode(text, 'utf-8')
u'\xe1'
>>> unicode(text, 'utf-8') == text.decode('utf-8')
True
现在,如果我有一个在方法中返回此文本的类__str__()
:
>>> class ReturnsEncoded(object):
... def __str__(self):
... return text
...
>>> r = ReturnsEncoded()
>>> str(r)
'\xc3\xa1'
unicode(r)
似乎使用str()
它,因为它引发了与上面相同的错误unicode(text)
:
>>> unicode(r)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0:
ordinal not in range(128)
到目前为止,一切都按计划进行!
但正如没有人会想到的那样,unicode(r, 'utf-8')
甚至不会尝试:
>>> unicode(r, 'utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: coercing to Unicode: need string or buffer, ReturnsEncoded found
为什么?为什么会出现这种不一致的行为?它是一个错误吗?是有意的吗?很尴尬。