Unicode和覆盖' __ str __'

时间:2015-09-11 22:10:24

标签: python string unicode

我只有在覆盖我的班级时才会收到unicode错误' __str__方法。发生了什么事?

Test.py

class Obj(object):

    def __init__(self):
        self.title = u'\u2018'

    def __str__(self):
        return self.title


print "1: ", Obj().title
print "2: ", str(Obj())

运行这个我得到:

$ python Test.py
1:  ‘
2: 
Traceback (most recent call last):
  File "Test.py", line 11, in <module>
    print "2: ", str(Obj())
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2018' in position 0: ordinal not in range(128)

编辑:请不要只说str(u'\u2018')也会引发错误!(虽然这可能是相关的)。这绕过了内置方法重载的全部目的 - 这个代码不应该调用str(u'\u2018') !!

2 个答案:

答案 0 :(得分:3)

你正在使用Python 2.x. str()调用__str__并希望您返回一个字符串,即str。但你不是;你正在返回一个unicode对象。因此,str()有助于将其转换为str,因为它应该返回str()

现在,在Python 2.x中,字符串是字节序列,不是代码点,因此Python正在尝试将Unicode对象转换为字节序列。由于您没有(并且在这种情况下不能)指定在创建字符串时使用的编码,因此Python使用ASCII的默认编码。这是失败的,因为ASCII不能代表角色。

可能的解决方案:

  1. 使用Python 3,其中所有字符串都是Unicode。这将为您提供一个有趣的不同的东西来包裹你的头,但这不会是其中之一。

  2. 在将对象转换为字符串时,覆盖__unicode__()而不是__str__()并使用unicode()代替str()。你仍然遇到如何将转换为正确输出的字节序列的问题(与Python 3共享)。

  3. 找出您的终端使用的编码(即sys.stdout.encoding)并让__str__()在返回之前将Unicode对象转换为该编码。请注意,仍然无法保证该字符在该编码中是可表示的;例如,您无法将示例字符串转换为默认的Windows终端编码。在这种情况下,你可以回到例如unicode-escape编码如果您尝试转换为输出编码时出现异常。

答案 1 :(得分:0)

问题是str()无法处理你的问题。 (unicode),因为它试图将其转换为ascii并且没有ascii字符。

>>> str(u'\u2018')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2018' in position 0: ordinal not in range(128)
>>> 

您可以查看this了解更多信息......