Python ASCII和Unicode解码错误

Ami*_*ash 14 python sqlite string character-encoding

将某个字符串插入数据库时​​,我遇到了非常令人沮丧的错误.它说:

Python无法解码字节字符,期待unicode"

经过大量的搜索,我看到我可以通过将我的字符串编码为Unicode来克服这个错误.我尝试首先解码字符串,然后以UTF-8格式对其进行编码.喜欢:

string = string.encode("utf8")
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

'ascii' codec can't decode byte 0xe3 in position 6: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)

我一直在为这个错误而死!我如何解决它?

Ned*_*der 49

你需要采取一种纪律严明的方法. 务实的Unicode,或者如何阻止痛苦?拥有你需要的一切.

如果你在那行代码上得到那个错误,那么问题是它string是一个字节字符串,并且Python 2隐式地尝试将它解码为Unicode.但它不是纯粹的ascii.您需要知道编码是什么,并正确解码.

  • 您可能还需要首先阅读:绝对最低每个软件开发人员绝对必须知道关于Unicode和字符集http://www.joelonsoftware.com/articles/Unicode.html (7认同)
  • @Esailija:这一点很小,并且有技术原因为什么"6字节"也是准确的.关于这篇文章的其他所有内容都很好. (2认同)

Syl*_*sne 12

encode应该在unicode对象上使用该方法将它们转换为str具有给定编码的对象.该decode方法应该用于str给定编码的unicode对象以转换它们的对象.

我想你的数据库以UTF-8存储字符串.因此,当您从数据库中获取字符串时,unicode通过执行将它们转换为对象str.decode('utf-8').然后只unicode在python程序中使用对象(文字定义为u'unicode string').就在将它们存储在数据库中之前,将它们转换为str对象uni.encode('utf-8').


Kar*_*jan 5

编辑:正如你从下降投票中看到的那样,这不是最好的方法。之后,一个很好的,强烈推荐的答案会立即出现,因此,如果您正在寻找一个好的解决方案,请使用它。这是一个骇人听闻的解决方案,在以后的时间不会对您友好。

我感到您很痛苦,由于相同的错误,我遇到了很多问题。我解决它的最简单方法(这可能不是最好的方法,并且取决于您的应用程序)是将事物转换为unicode,并忽略错误。这是Unicode HOWTO的示例-Python v2.7.3文档

>>> unicode('\x80abc', errors='strict')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0:
                    ordinal not in range(128)
>>> unicode('\x80abc', errors='replace')
u'\ufffdabc'
>>> unicode('\x80abc', errors='ignore')
u'abc'
Run Code Online (Sandbox Code Playgroud)

尽管这可能不是最方便的方法,但是对我来说这是一种有效的方法。

编辑:

评论中的几个人提到这是个坏主意,即使询问者接受了答案。这不是一个好主意,如果您要处理带有欧洲字母和重音符号的字符,它会弄糟。但是,如果不是生产级代码,或者您正在处理的是个人项目,则可以使用此工具,并且需要快速修复才能使工作顺利进行。您最终将需要使用正确的方法来修复它,下面的答案中对此进行了提及。

  • 这将使用默认编码,即ASCII,并丢弃所有无法解释为ASCII的内容。换句话说,您将失去所有带重音符号或非欧洲字符。这似乎是个坏主意。-1。 (17认同)
  • 这可能是个坏主意,因为您会破坏源字符串中“decode()”在 ASCII 中无法匹配的每个字符,从而破坏数据。如果您将此信息写入数据库,则数据完整性可能对您很重要。-1 (2认同)
  • 我知道这是一个坏主意,我确实说过“这可能不是最好的方法”。有更干净的方法可以执行此操作,如下所述,但是,如果这不是生产级程序,或者只是为了让一个小小的个人黑客正常工作(这就是我用的目的),那是一个做到的方式。 (2认同)
  • @KarthikRangarajan:您至少可以提到他的数据实际上发生了什么... (2认同)