__str __()调用场景后面的decode()方法吗?

时间:2009-08-12 18:03:29

标签: python django string unicode

在我看来,内置函数__repr____str__在其基本定义上有重要区别。

>>> t2 = u'\u0131\u015f\u0131k'
>>> print t2
ışık
>>> t2
Out[0]: u'\u0131\u015f\u0131k'

t2.decode引发错误,因为t2是一个unicode字符串。

>>> enc = 'utf-8'
>>> t2.decode(enc)
------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython console>", line 1, in <module>
  File "C:\java\python\Python25\Lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordin
al not in range(128)

__str__会引发错误,就像调用decode()函数一样:

>>> t2.__str__()
------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython console>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordin
al not in range(128)

但是__repr__没有问题:

>>> t2.__repr__()
Out[0]: "u'\\u0131\\u015f\\u0131k'"

为什么__str__会产生错误而__repr__正常工作?

这个小差异似乎导致我正在处理的一个django应用程序中出现错误。

4 个答案:

答案 0 :(得分:7)

基本上,__str__只能输出ascii字符串。由于t2包含ascii以上的unicode代码点,因此无法仅使用字符串表示。另一方面,__repr__尝试输出重新创建对象所需的python代码。您将看到repr(t2)的输出(此语法优先于t2.__repr_())正是您在第一行上将t2设置为等于up。 repr的结果大致类似于['\','u','0',...],这些都是ascii值,但str的输出试图为[chr(0x0131),chr(0x015f) ,chr(0x0131),'k'],其中大部分都在python字符串中可接受的字符范围之上。通常,在处理django应用程序时,您应该对所有内容使用__unicode__,而不要触摸__str__

the django documentation on strings中的更多信息。

答案 1 :(得分:5)

通常,调用str.__unicode__()unicode.__str__()是一个非常糟糕的主意,因为字节无法安全地转换为Unicode字符点,反之亦然。例外是ASCII值,在所有单字节编码中通常是相同的。问题是您使用了错误的转换方法。

要将unicode转换为str,您应该使用encode()

>>> t1 = u"\u0131\u015f\u0131k"
>>> t1.encode("utf-8")
'\xc4\xb1\xc5\x9f\xc4\xb1k'

要将str转换为unicode,请使用decode()

>>> t2 = '\xc4\xb1\xc5\x9f\xc4\xb1k'
>>> t2.decode("utf-8")
u'\u0131\u015f\u0131k'

答案 2 :(得分:2)

为John的好答案添加一些支持:

要理解两个方法 encode() decode()的命名,您只需要看到Python考虑 u形式的unicode字符串'...'采用参考格式编码从参考格式转换为另一种格式(例如utf-8),并且解码从其他格式转换为参考格式。 unicode格式始终被认为是“真实的东西”: - )。

答案 3 :(得分:0)

请注意,在Python 3中,unicode是默认设置,__str__()应始终为您提供unicode。