Python – 'ascii'编解码器不能解码字节
我很困惑。 我试图编码,但错误说can't decode...
>>> "你好".encode("utf8") Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
我知道如何避免string上带有“u”前缀的错误。 我只是想知道为什么错误是“无法解码”时调用编码。 Python在做什么?
"你好".encode('utf-8')
encode
将一个unicode对象转换为一个string
对象。 但是在这里你已经在一个string
对象上调用它(因为你没有你)。 所以Python必须首先将string
转换为一个unicode
对象。 所以它相当于
"你好".decode().encode('utf-8')
但解码失败,因为该string是无效的ascii。 这就是为什么你会抱怨无法解码。
总是从unicode 编码为字节。
在这个方向上, 你可以select编码 。
>>> u"你好".encode("utf8") '\xe4\xbd\xa0\xe5\xa5\xbd' >>> print _你好
另一种方法是从字节解码到Unicode。
在这个方向上, 你必须知道编码是什么 。
>>> bytes = '\xe4\xbd\xa0\xe5\xa5\xbd' >>> print bytes你好>>> bytes.decode('utf-8') u'\u4f60\u597d' >>> print _你好
这一点不能太强调。 如果你想避免播放unicode“whack-a-mole”,那么了解数据层面发生了什么很重要。 这里以另一种方式解释:
- 一个unicode对象已经被解码了,你永远不想调用它的
decode
。 - 一个string对象已经被编码了,你永远不想调用它的
encode
。
现在,看到一个字节string上的.encode
,Python 2首先尝试隐式地将其转换为文本(一个unicode
对象)。 同样的,在看到unicodestring上的.decode
时,Python 2会隐式地尝试将其转换为字节(一个str
对象)。
这些隐式转换是为什么当你调用encode
时可以得到Unicode
Decode
Error
。 这是因为编码通常接受一个unicode
types的参数; 当接收到str
参数时,在用另一个编码对其进行重新编码之前,会隐式解码unicode
types的对象。 这个转换select一个默认的“ascii”解码器,给你一个编码器内的解码错误。
事实上,在Python 3中, str.decode
和bytes.encode
方法都不存在。 他们的搬迁是一个有争议的尝试,以避免这种常见的混乱。
† …或任何编码sys.getdefaultencoding()
提到; 通常这是'ascii'
你可以试试这个
import sys reload(sys) sys.setdefaultencoding("utf-8")
要么
您也可以尝试以下操作
在.py文件的顶部添加以下行。
# -*- coding: utf-8 -*-
如果你使用Python <3,你需要告诉解释器你的string是Unicode,前缀为u
:
Python 2.7.2 (default, Jan 14 2012, 23:14:09) [GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> "你好".encode("utf8") Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128) >>> u"你好".encode("utf8") '\xe4\xbd\xa0\xe5\xa5\xbd'
进一步阅读 : Unicode HOWTO 。
你用u"你好".encode('utf8')
来编码一个unicodestring。 但是如果你想代表"你好"
,你应该解码它。 就像:
"你好".decode("utf8")
你会得到你想要的。 也许你应该学习更多的编码和解码。
如果你正在处理Unicode,有时候而不是encode('utf-8')
,你也可以尝试忽略特殊字符,例如
"你好".encode('ascii','ignore')
或something.decode('unicode_escape').encode('ascii','ignore')
如这里所build议的 。
在这个例子中不是特别有用,但是在其他情况下不能转换某些特殊字符时可以更好地工作。
或者,您可以考虑使用replace()
replace特定的字符 。