Python - 'ascii'编解码器无法解码字节

tho*_*lin 113 python unicode python-2.x python-2.7 python-unicode

我真的很困惑.我试着编码,但错误说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)
Run Code Online (Sandbox Code Playgroud)

我知道如何避免字符串上带有"u"前缀的错误.我只是想知道为什么在调用编码时错误是"无法解码".什么是Python在幕后做什么?

Win*_*ert 160

"??".encode('utf-8')
Run Code Online (Sandbox Code Playgroud)

encode将unicode对象转换为string对象.但是你在这里调用了一个string对象(因为你没有你).所以python必须先将对象转换stringunicode对象.所以它确实相当于

"??".decode().encode('utf-8')
Run Code Online (Sandbox Code Playgroud)

但解码失败,因为字符串无效ascii.这就是为什么你得到一个关于无法解码的投诉.

  • 那么解决方案是什么?特别是如果我没有字符串文字,我只有一个字符串对象. (48认同)
  • 所以要从上面清楚地说明你可以"你好".decode('utf-8').encode('utf-8')` (19认同)
  • @deinonychusaur,有什么意义呢? (11认同)
  • @WinstonEwert我想我很困惑.编码业务往往让我永远感到困惑.我想我的困惑来自于我自己的问题,即不知道输入是字符串还是unicode字符串以及它可能具有的编码. (5认同)
  • @JonTirsen,你不应该编码一个字符串对象.字符串对象已经编码.如果需要更改编码,则需要将其解码为unicode字符串,然后将其编码为所需的编码. (2认同)

wim*_*wim 52

始终从unicode 编码为字节.
在这个方向上,您可以选择编码.

>>> u"??".encode("utf8")
'\xe4\xbd\xa0\xe5\xa5\xbd'
>>> print _
??
Run Code Online (Sandbox Code Playgroud)

另一种方法是从字节解码到unicode.
在这个方向上,您必须知道编码是什么.

>>> bytes = '\xe4\xbd\xa0\xe5\xa5\xbd'
>>> print bytes
??
>>> bytes.decode('utf-8')
u'\u4f60\u597d'
>>> print _
??
Run Code Online (Sandbox Code Playgroud)

这一点不够强调.如果你想避免玩unicode"whack-a-mole",重要的是要了解数据层面发生了什么.这里解释另一种方式:

  • unicode对象已经被解码,你永远不想调用decode它.
  • bytestring对象已经编码,你永远不想调用encode它.

现在,在查看.encode字节字符串时,Python 2首先尝试将其隐式转换为文本(unicode对象).类似地,在查看.decodeunicode字符串时,Python 2会隐式尝试将其转换为字节(str对象).

这些隐含的转换是你打电话的原因.这是因为编码通常接受类型的参数; 当接收参数时,在用另一种编码重新编码之前,对类型的对象进行隐式解码.此转换选择默认的'ascii'解码器,为您提供编码器内的解码错误.UnicodeDecodeErrorencodeunicodestrunicode

事实上,在Python 3的方法str.decodebytes.encode甚至不存在.他们被撤职是一种[有争议的]企图避免这种常见的混乱.

...或任何编码sys.getdefaultencoding()提及; 通常这是'ascii'

  • @NoBugs 1. 在 REPL 中,`_` 指的是之前的值 2. 因为这是一个 python-2.x 问题。 (2认同)

Dad*_*ane 39

你可以试试这个

import sys
reload(sys)
sys.setdefaultencoding("utf-8")
Run Code Online (Sandbox Code Playgroud)

要么

您也可以尝试以下

在.py文件的顶部添加以下行.

# -*- coding: utf-8 -*- 
Run Code Online (Sandbox Code Playgroud)


Joh*_*web 8

如果你正在使用Python <3,你需要告诉解释,你通过与它的前缀字符串文字是Unicodeu:

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'
Run Code Online (Sandbox Code Playgroud)

进一步阅读:Unicode HOWTO.

  • 如果你正在编码一个字符串,为什么它会抛出一个解码错误? (4认同)