【问题标题】:__str__ returns UnicodeEncodeError, but otherwise works (u'\xa0')__str__ 返回 UnicodeEncodeError,但否则有效 (u'\xa0')
【发布时间】:2014-01-03 10:10:39
【问题描述】:

我遇到了我一生中最奇怪的错误。

我正在修复我的Hacker News API,这段代码让我很头疼:

from hn import HN

hn = HN()


# print top stories from homepage
for story in hn.get_stories():
    print story.title
    print story

Story__str__方法如下:

def __str__(self):
    """
    Return string representation of a story
    """
    return self.title

(这与repo中的代码有点不同。我必须在这里调试很多。)

不管怎样,输出是这样的:

Turn O(n^2) reverse into O(n)
Turn O(n^2) reverse into O(n)
My run-in with unauthorised Litecoin mining on AWS
My run-in with unauthorised Litecoin mining on AWS
Amazon takes away access to purchased Christmas movie during Christmas
Traceback (most recent call last):
  File "my_test_bot.py", line 11, in <module>
    print story
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 60: ordinal not in range(128)

我不知道为什么会失败。 __str__print story 语句都打印一个 unicode。那么为什么后者不起作用?

另外,print unicode(story) 工作得很好(为什么??),但不幸的是我不能使用unicode(),因为它不兼容 py3。

title 编码为:title.encode('cp850', errors='replace').decode('cp850')

这里到底发生了什么?如何确保我的 API 适用于它可以找到的任何(意味着大多数)字符串并且 py2 和 py3 兼容?

我有 downloaded the page 正在导致此错误以进行离线调试。

【问题讨论】:

  • 您应该使用str.encodestr.decode 方法。要么只使用我不推荐的字节数组(py2 样式),要么只使用 unicode 字符串(使用str.encodeprint(u"Hello")。顺便说一句,如果你想同时兼容 py2 和 py3 ,使用 print 作为函数而不是关键字。目前您的问题是您正在尝试使用 ascii 编解码器解码 unicode 字符。这将永远无法工作。永远。:P

标签: python python-2.7 python-3.x unicode encoding


【解决方案1】:

当您尝试将输出保存到文件而不是打印时,通常可以解释这种讨厌的问题。试试:

for story in hn.get_stories():
    print type(story.title)
    print type(story)

    with open('content.txt', 'ab') as f:
        f.write(story.title)
        f.write('\n\n')
        f.write(story)
        f.write('\n-----------------------------------------------\n')

我希望这是解决方案的迭代方法。需要更多的事实。你可能被某些东西误导了。

【讨论】:

    【解决方案2】:

    __str__ 返回一个字节数组,没有任何有关编码的信息,您的控制台应用程序可能会尝试将 __str__ 返回的任何内容编码为 ascii 并失败。您可以尝试使用返回字符的__unicode__this answer 中有更多信息。

    是的,py3 只有__str__ 元数据,所以你必须保留__unicode__ 以保持兼容性

    【讨论】:

    • 这并不能解释为什么print story.title 显然有效但print story 无效,因为根据他的代码,它们应该具有相同的结果。
    • @BrenBam,不一定:print story.title 隐式计算 str(story.title) 并打印结果。但是print story 隐式计算str(story),即story.__str__(),它返回story.title。在后一种情况下,内置的str()应用于story.title,仅在前一种情况下。
    • 并非如此。这并没有真正奏效。 return '[{0}]: "{1}" by {2}'.format(self.points, self.title, self.submitter) in __unicode__ 仍然会导致错误。
    • @KaranGoel,对于您的 __unicode__ 方法,如果您仅支持 Python 3 版本 3.3+,则可以使用 u'' 文字。否则,您可以在调用format 方法之前解码模板。对于统一的 2 和 3 代码库,请考虑使用 Six
    • __unicode__ 中添加u 在py2 中起到了作用。你能推荐一些资源,让我可以了解更多关于 py2 和 py3 编码并修复这个错误吗?
    猜你喜欢
    • 1970-01-01
    • 2017-05-30
    • 1970-01-01
    • 2014-04-12
    • 2020-04-13
    • 2016-11-06
    • 2019-08-21
    • 2018-07-10
    • 2012-04-14
    相关资源
    最近更新 更多