python字节字符串编码和解码

python字节字符串编码和解码,python,json,unicode,utf-8,python-unicode,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”是通过google协议缓

我正在尝试将包含非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”是通过google协议缓冲区从mysql来的,并用一些blob数据填充

有什么想法吗

编辑: 我有以太网帧,它们以blob的形式存储在mysql表中(请大家继续关注主题,不要讨论为什么表中有数据包)。表排序规则是utf-8,数据库层(sqlalchemy,非orm)正在获取数据并创建结构(google协议缓冲区),将blob存储为python“str”。在某些情况下,我直接使用协议缓冲区而没有任何问题。在其他情况下,我需要通过json公开相同的数据。我注意到,当json.dumps()起作用时,“\x80”可以替换为无效的unicode字符(\ufffd iirc)

使用
b.decode('source encoding的名称')
获得unicode版本。当我得知这一点时,我感到很惊讶。例如:

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

您需要检查正在使用的软件API的文档。BLOB是一个缩写:二进制大对象

如果您的数据实际上是二进制的,那么将其解码为Unicode的想法当然是胡说八道

如果它实际上是文本,您需要知道使用什么编码将其解码为Unicode

然后使用
json.dumps(一个Python对象)
。。。如果您自己将其编码为UTF-8,
json
将再次对其进行解码:

>>> import json
>>> json.dumps(u"\u0100\u0404")
'"\\u0100\\u0404"'
>>> json.dumps(u"\u0100\u0404".encode('utf8'))
'"\\u0100\\u0404"'
>>>
关于拉丁语1的更新:


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

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

unicode_b = b.decode('some_encoding')
然后使用utf_8编码将unicode对象重新编码回字符串对象

b = unicode_b.encode('utf_8')

使用unicode对象作为转换器,在不知道字符串的原始编码是什么的情况下,我无法确定,但有可能转换不会按预期进行。unicode对象不用于将一种编码的字符串转换为另一种编码。我会使用unicode对象,假设您知道编码是什么,如果您不知道编码是什么,那么就真的没有办法不经过反复试验就找到,然后在您想要返回字符串对象时再转换回编码字符串。

请记住:
解码
从字节转换为unicode<代码>编码从unicode到字节。@DanielRoseman是的,这就是为什么这是问题的答案。当然,我不是在争论,只是为OP提供了一些额外的解释。我提出了同样的想法,但似乎效率太低了。我很惊讶没有一种直接对字节字符串进行utf-8编码的方法。@kung-foo你是什么意思?这在什么方面不是“直接的”?很有趣。我想我可以保持简单:打印json.dumps('\x80'.decode('latin1'))@kung foo:你没有证据表明
latin1
是正确的编码。那么将一个字节串编码成utf-8的方法是什么?BLOB是从哪里来的?@kung foo:这个方法是一个字节串。decode('some_编码')。encode('utf8')。。。但是,您不需要编码成utf8就可以使用
json.dumps
;您确实需要确定您的数据是否为文本,如果是,那么什么是
某些编码
,并且
latin1
不太可能。。。嗯,换言之:只要慢慢仔细地重新阅读我的答案,你需要给出一个代码片段,说明“直接使用协议缓冲区而不产生任何问题”的含义。您需要用一个代码片段显示如何使用协议缓冲区来生成
json.dumps
product\ufffd。您需要确切地说明这个JSONised数据包的使用者希望如何恢复原始数据包。