python字节串编码和解码

时间:2012-03-07 15:54:15

标签: python json unicode utf-8 python-unicode

我正在尝试将包含非ascii字符的传入字节字符串转换为有效的utf-8字符串,以便我可以将其转储为json。

b = '\x80'
u8 = b.encode('utf-8')
j = json.dumps(u8)

我希望j为'\ xc2 \ x80',但我得到:

UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0: ordinal not in range(128)

在我的情况下,'b'来自mysql通过谷歌协议缓冲区,并填写了一些blob数据。

有什么想法吗?

编辑: 我有以太网帧作为blob存储在mysql表中(请大家,请保持主题,不要讨论为什么表中有数据包)。表格排序是utf-8,db层(sqlalchemy,non-orm)正在抓取数据并创建结构(谷歌协议缓冲区),它将blob存储为python“str”。在某些情况下,我直接使用协议缓冲区,没有任何问题。在其他情况下,我需要通过json公开相同的数据。我注意到的是,当json.dumps()做了它的事情,'\ x80'可以用无效的unicode char替换(\ ufffd iirc)

3 个答案:

答案 0 :(得分:9)

您需要检查您正在使用的软件API的文档。 BLOB是首字母缩略词: BINARY 大对象。

如果您的数据实际上是二进制的,那么将其解码为Unicode的想法当然是无稽之谈。

如果它实际上是文本,则需要知道使用哪种编码将其解码为Unicode。

然后你使用json.dumps(a_Python_object) ...如果你自己编码为UTF-8,json会再次解码它:

>>> import json
>>> json.dumps(u"\u0100\u0404")
'"\\u0100\\u0404"'
>>> json.dumps(u"\u0100\u0404".encode('utf8'))
'"\\u0100\\u0404"'
>>>

关于latin1

的更新

u'\x80'是一个无用的无意义的C1控制字符 - 编码极不可能是Latin-1。 Latin-1是“陷阱和妄想” - 所有8位字节都被解码为Unicode而不会引发异常。不要混淆“作品”和“不引起异常”。

答案 1 :(得分:6)

使用b.decode('name of source encoding')获取unicode版本。当我学到它时,这对我来说是令人惊讶的。例如:

In [123]: 'foo'.decode('latin-1')
Out[123]: u'foo'

答案 2 :(得分:2)

我认为你要做的是解码某些编码的字符串对象。你知道编码是什么吗?获取unicode对象。

unicode_b = b.decode('some_encoding')

然后使用utf_8编码将unicode对象重新编码回字符串对象。

b = unicode_b.encode('utf_8')

使用unicode对象作为翻译器,不知道字符串的原始编码是什么,我无法确定,但转换可能不会按预期进行。 unicode对象不用于将一种编码的字符串转换为另一种编码。假设您知道编码是什么,我会使用unicode对象,如果您不知道编码是什么,那么在没有试验和错误的情况下确实没有找到方法,然后转换回编码的字符串时你想要一个字符串对象。