美文网首页
python2.7 json.loads() 将字符串默认解码为

python2.7 json.loads() 将字符串默认解码为

作者: zbharper | 来源:发表于2019-05-16 16:11 被阅读0次

python2.7 中 str 与 unicode 的转换一直是个头疼的问题,在使用json模块进行序列化与反序列化时再次踩坑。

1)客户端产生一个字典格式的数据结构,其中带有一段utf-8编码的字符串

import json

raw = u"我爱中国".encode("utf-8")
send_data = {
    "id": 111,     #不重要
    "content": raw   # 数据内容为utf-8编码
}

print type(send_data['content'])    # str

2)客户端将数据进行json序列化,通过消息队列发送至服务器

send_body = json.dumps(send_data)
# send to rabbitmq

3)服务器端收到后进行解码,交给后端处理

# receive_body get from rabbitmq
receive_data = json.loads(receive_body)

4)后端使用数据,此时数据已经是unicode 而不是utf-8,再次解码会出错!

print type(receive.data['content'])   # unicode

从协议分层的角度,(1)与(4)处于同一逻辑层,抛开(2),(3)的json序列化与反序列化过程,发送与接收的数据格式应该相同,但是receive_data 与 send_data中的字符编码不一样,稍不注意使用(如按数据格式协议解码)就会出错。

查看json官方文档,发现在反序列化json.loads()的过程中会自动将所有字符串解码为unicode格式。而序列化过程json.dumps()会默认将非ascii编码的字符转换为unicode,同时可以通过参数ensure_ascii=False选择保持原有编码不变。有点绕,但是坑爹的地方就在于此,做几个实验:

1. 默认参数不变,对两种编码( utf8, unicode)进行序列化
>>> unicode_str = u"abc我爱中国def"     # u'abc\u6211\u7231\u4e2d\u56fddef'
>>> utf8_str = unicode_str.encode('utf-8')   # 'abc\xe6\x88\x91\xe7\x88\xb1\xe4\xb8\xad\xe5\x9b\xbddef'

>>> ser1 = json.dumps(unicode_str)
>>> ser2 = json.dumps(utf8_str)
>>> ser1
'"abc\\u6211\\u7231\\u4e2d\\u56fddef"'
>>> ser2
'"abc\\u6211\\u7231\\u4e2d\\u56fddef"' 

输入不同,序列化之后的结果相同!

2. 使用json.dumps(obj, ensure_ascii=False), 对两种编码进行序列化
>>> ser3 = json.dumps(unicode_str, ensure_ascii=False)
>>> ser4 = json.dumps(utf8_str, ensure_ascii=False)
>>> ser3
u'"abc\u6211\u7231\u4e2d\u56fddef"'
>>> ser4
'"abc\xe6\x88\x91\xe7\x88\xb1\xe4\xb8\xad\xe5\x9b\xbddef"'

序列化后的结果不同!分别保持了原有的编码!

3. 对上述的序列化字符串进行反序列化
>>> new1 = json.loads(ser1)
>>> new2 = json.loads(ser2)
>>> new3 = json.loads(ser3)
>>> new4 = json.loads(ser4)
>>> new1
u'abc\u6211\u7231\u4e2d\u56fddef'
>>> new2
u'abc\u6211\u7231\u4e2d\u56fddef'
>>> new3
u'abc\u6211\u7231\u4e2d\u56fddef'
>>> new4
u'abc\u6211\u7231\u4e2d\u56fddef'

四个序列化字符串反序列化结果全都相同!

结论

  1. 反序列化后总会得到unicode字符串,无论序列化阶段如何搞
  2. 序列化阶段通过参数设置,可能生成不同的序列化结果
  3. 要想少出错,在上层的数据协议里最好将字符串都定义为unicode格式
  4. 尽快转到python3

相关文章

  • python2.7 json.loads() 将字符串默认解码为

    python2.7 中 str 与 unicode 的转换一直是个头疼的问题,在使用json模块进行序列化与反序列...

  • Python——JSON

    json.loads() json.loads 用于解码 JSON 数据,将Json格式字符串解码转换成Pytho...

  • json.loads()、json.load()、json.du

    1、json.loads()和json.dumps() 处理字符串 json.loads()将字符串转换为字典类型...

  • python json模块使用时关于中文编码的问题

    json.loads() json.loads()将json字符串转化为python对象时的对应关系如下:映射关系...

  • json/编码

    json.dumps() 将字典转化为字符串 json.loads()将字符串转化为字典 json.dump()将...

  • python json 模块

    json转换 json.dumps() 将字典对象转换为字符串 json.loads() 将字符串对象转换为字典 ...

  • json、多任务

    json json.loads() : 将json字符串转化为Python数据类型json.dumps() : 将...

  • json处理

    读取json格式字符串 json.loads(str) 将字符串转换为json json.dump(json)

  • json

    json.dumps 将 Python 对象编码成 JSON 字符串 json.loads 将已编码的 JSON ...

  • python json模块

    json.dumps 将 Python 对象编码成 JSON 字符串 json.loads 将已编码的 JS...

网友评论

      本文标题:python2.7 json.loads() 将字符串默认解码为

      本文链接:https://www.haomeiwen.com/subject/kdyiaqtx.html