python字节串编码和解码

kun*_*foo 10 python unicode json utf-8 python-unicode

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

b = '\x80'
u8 = b.encode('utf-8')
j = json.dumps(u8)
Run Code Online (Sandbox Code Playgroud)

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

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

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

有任何想法吗?

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

Joh*_*hin 9

您需要检查您正在使用的软件API的文档.BLOB是首字母缩略词:BINARY Large Object.

如果您的数据实际上是二进制的,那么将其解码为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"'
>>>
Run Code Online (Sandbox Code Playgroud)

更新latin1:

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


Mar*_*cin 6

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

In [123]: 'foo'.decode('latin-1')
Out[123]: u'foo'
Run Code Online (Sandbox Code Playgroud)

  • 记住:`decode`从字节到unicode.`encode`从unicode变为bytes. (9认同)