序列化和反序列化
simplejson

概述

REST API 是 在全世界使用标准化的消息格式。JSON 是互联网上数据交换的基石,作为 JavaScript 的一个子集,它从一开始就获得了巨大的推广。它特别清晰易读的语法也有利于推广
据我所知各种语言都有 JSON 库用于序列化和反序列化。实际上在 Python 中就有很多种 JSON 库,如在之前的文章中就介绍过JMESPath的使用

序列化和反序列化

通过文件操作,可以将字符串写入到一个本地文件。但是,如果是一个对象(如列表、字典、元组等),就无法直接写入到一个文件里,需要对这个对象进行序列化,然后才能写入到文件里

  • 序列化:将数据从内存持久化保存到硬盘的过程
  • 反序列化:将数据从硬盘加载到内存的过程

python中json数据的序列化和反序列化

  • 序列化:将python对象转换成json字符串,可使用json.dumps()和json.dump()
  • 反序列化:将json字符串转换成python对象,可使用json.loads()和json.load()

初学者经常分不清是使用load(s)方法还是dump(s)方法,其实记住load(装载,装进来),dump(倾倒,倒出去)的英文翻译就更容易理解了,装进来就是反序列化,倒出去就是序列化
内建库json的使用示例可参看之前的文章json库的介绍

simplejson

CPython有一个json模块。它最初是由Bob Ippolito作为simplejson开发的,并被合并到Python 2.4。simplejson 仍然作为一个单独的库存在,使用它需要先安装

pip3 install simplejson

相关文档

simplejson与json

simplejson的使用

simplejson的使用方法与json使用方法基本一致

  • json.loads和simplejson.loads
# json.loads
def loads(s, *, cls=None, object_hook=None, parse_float=None,
        parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
...

# simplejson.loads
def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
        parse_int=None, parse_constant=None, object_pairs_hook=None,
        use_decimal=False, **kw):
...
  • json.dumps和simplejson.dumps
# json.dumps
def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,
        allow_nan=True, cls=None, indent=None, separators=None,
        default=None, sort_keys=False, **kw):
...

# simplejson.dumps
def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
          allow_nan=True, cls=None, indent=None, separators=None,
          encoding='utf-8', default=None, use_decimal=True,
          namedtuple_as_object=True, tuple_as_array=True,
          bigint_as_string=False, sort_keys=False, item_sort_key=None,
          for_json=False, ignore_nan=False, int_as_string_bitcount=None,
          iterable_as_array=False, **kw):
...

具体参数说明可参考api文档或源码中的docs说明

  • 使用示例1(注意区别)
import simplejson
import json

s = b'abc'
a = simplejson.dumps(s)
print(a, type(a))
# b = json.dumps(s) # TypeError: Object of type bytes is not JSON serializable
# print(a, type(a))
--------------输出结果-------------
"abc" <class 'str'>
  • 使用示例2:test文件中多行json字符串
import simplejson as json

def loads_lines(docs):
    for doc in docs.splitlines():
        yield json.loads(doc)

with open('test', 'r') as f:
    for doc in loads_lines(f.read()):
        print(doc)
  • 库导入实践
try:
    import simplejson as json
except ImportError:
    import json

这样写的效果是,优先导入三方库 simplejson,如果找不到,那就使用内置的标准库 json

命令行

  • 使用simplejson.tool在shell中验证和格式化打印json字符串,使用与json.tool一致
  1. json字符串
$ echo '{"a":1,"b":2}' | python -m simplejson.tool
{
    "a": 1,
    "b": 2
}

$ echo '{ 1.2:3.4}' | python -m simplejson.tool
Expecting property name enclosed in double quotes: line 1 column 3 (char 2)
  1. json字符串文件,如test.json存放{"a":1, "b":2}
$ python -m simplejson.tool test.json
{
    "a": 1,
    "b": 2
}
  • 扩展命令jq:使用jq命令来验证和格式化
$ echo '{"a":1,"b":2}' | jq
{
  "a": 1,
  "b": 2
}

$ echo '{ 1.2:3.4}' | jq
parse error: Object keys must be strings at line 1, column 6

$ cat test.json | jq
{
  "a": 1,
  "b": 2
}

扩展阅读

  1. 廖雪峰的python教程:序列化
  2. Python中数据的序列化和反序列化
  3. Python 的 JSON 库:按速度,成熟度和操作安全性进行比较