【问题标题】:Python: UnicodeEncodeError 'ascii' codecPython:UnicodeEncodeError 'ascii' 编解码器
【发布时间】:2014-01-13 09:07:14
【问题描述】:

我只想让 python 代码工作,但我不理解这些转换错误(我总是得到某种类型的“ascii”编码或解码错误)。我发疯了,对生产线的每一部分都进行了解码和编码,但它仍然给我带来了麻烦。如果您愿意纠正它,可以通过 GIT 在https://github.com/TBOpen/papercut 获得它(我还使用self.wfile.write(message.decode('cp1250', 'replace').encode('ascii', 'replace') + "\r\n") 解决了未在第 885 行签入的类似错误。

但是,这是我无法解决的问题(我放弃的地方)的回溯。

Traceback (most recent call last):
  File "/usr/local/lib/python2.6/SocketServer.py", line 535, in process_request
    self.finish_request(request, client_address)
  File "/usr/local/lib/python2.6/SocketServer.py", line 320, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/local/lib/python2.6/SocketServer.py", line 615, in __init__
    self.handle()
  File "./papercut.py", line 221, in handle
    getattr(self, "do_%s" % (command))()
  File "./papercut.py", line 410, in do_ARTICLE
    self.send_response("%s\r\n%s\r\n\r\n%s\r\n.".decode('cp1250', 'replace').encode('ascii', 'replace') % (response.decode('cp1250', 'replace').encode('ascii', 'replace'), result[0].decode('cp1250', 'replace').encode('ascii', 'replace'), result[1].decode('cp1250', 'replace').encode('ascii', 'replace')))
  File "/usr/local/lib/python2.6/encodings/cp1250.py", line 15, in decode
    return codecs.charmap_decode(input,errors,decoding_table)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2122' in position 20: ordinal not in range(128)

TIA!!

【问题讨论】:

  • 你使用的是python 2.x还是python 3.x?
  • @mig-25foxbat:Python 2.6,来自追溯。
  • 你能把你的py代码贴出来吗?
  • 这是一种非常不可读和不可调试的做事方式。为什么不在输入端解码所有输入,将所有内容(包括 % 格式)处理为 Unicode,然后在输出端进行编码,而不是到处进行解码和编码?
  • 你不需要解码,然后编码你的字符串模板(带有%s占位符的字符串);它已经只是 ASCII。

标签: python


【解决方案1】:

根本问题是responseresult[0]result[1] 之一实际上是unicode 字符串,而不是编码的str 字符串。

因此,当您调用(任意选择一个)response.decode('cp1250', 'replace') 时,您要求解码已解码为 Unicode 的内容。 Python 2.x 对此所做的是首先将其编码为您的默认编码 (ASCII),以便它可以按照您的要求对其进行解码。这就是为什么您尝试拨打 decode 会得到 UnicodeEncodeError。*

要解决此问题,您必须弄清楚这三个中的哪一个是错误的,以及为什么。这对于包含 4 个解码调用的大量语句来说是不可能的,但是如果你将它分解成单独的语句,或者只是添加一些 print 调试以在这些变量被使用之前查看它们中的内容,这很容易。

但是,完全重新组织代码会让您的生活变得更加轻松。与其在整个地方来回转换所有内容,不如给自己几十个地方犯一个简单的错误,最终导致程序中途出现不可调试的错误,只需在输入时解码所有输入,将所有内容处理为 Unicode ,然后在输出时对所有内容进行编码。

顺便说一句,如果您还没有阅读 Python 的 Unicode HOWTO 和博客文章 The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!),请在继续阅读之前阅读它们。


* 如果你认为这是一种愚蠢的语言设计……嗯,这就是 Python 3 存在的主要原因。在 Python 3 中,您不能 decode a unicodeencode a bytes,因此错误会尽早出现,并告诉您确切的问题所在,而不是让您尝试寻找你在错误的类型上调用了错误的方法并得到了一个没有意义的错误。因此,如果您想使用 Python 2 而不是 3,您不必抱怨 Python 2 的设计比 3 的更傻。

【讨论】:

    猜你喜欢
    • 2012-01-07
    • 2015-04-08
    • 1970-01-01
    • 2015-08-12
    • 2016-10-03
    • 2011-09-26
    • 1970-01-01
    • 2017-03-01
    • 1970-01-01
    相关资源
    最近更新 更多