Skip to content

json

json 是标准库提供的 JSON 格式的序列化和反序列化库。

接口

python 标准库的序列化和反序列化接口都是相似的(例如 pickle 也同样如此):

  • 序列化: dump(obj, fp)/dumps(obj) -> str
  • 反序列化: load(fp) -> any/loads(input: str) -> any

区别就在于 dump/load 接受 file-like 对象,而 dumps/loads 接受字符串,除此之外的其他参数都是一样的。

序列化: dump

所谓的序列化就是将 Python 对象根据转换表来生成 JSON 对象:

Python
dump(
    obj, # 要转换的对象
    fp,  # file-like 对象(结果写入的文件),对于 dumps 来说不存在该参数
    skipkeys:bool=False, # 如果为 True 则不是基本数据类型(str int float bool None)的键被跳过,否则引发 TypeError
    ensure_assii:bool=True, # 默认将所有非 ASCII 字符转义
    allow_nan:bool=True, # 主要针对于 float,如果为 False 严格遵循 float 的取值,而 True 会将他们转换为 js 等价形式(NaN Infinity -Infinity)
    indent:str|int|None=None, # 相当于格式化,None 是紧凑,2 表示两个空格,"\t" 即 tab
    separators:tuple|None=None,  # 接受 (item_separator, key_separator)元组作为分隔符,默认是 (",", ":")
    default:Callable|None=None, # 接受一个函数,单某个对象无法被序列化时调用他
    sort_keys:bool=False, # 如果为 True 输出以键的顺序排序
):
    pass
# 如果是 dumps 返回 str

反序列化: load

所谓的反序列化就是将字符串或文件对象中的内容根据转换表来生成 Python 对象:

Python
load(
    fp, # file-like 对象(读取其中的内容),对于 loads 来说是 str/bytes
    obejct_hook:Callable|None=None, # 结果对象(dict)会调用该方法处理后输出
    parse_float:Callable|None=None, # 解析浮点数字符串的函数,默认 float(num_str)
    parse_int:Callable|None=None, # 解析整数字符串的函数,默认 int(num_str)
) -> dict
    pass

转换表

默认情况下 json 转换表如下:

JSON Python
object dict
array list
string str
number(int) int
number(real) float
true True
false False
null None

如果想要扩展其他对象,需要通过 default 参数来实现。dump 过程中任何无法被序列化的对象都会传递给该参数指向的函数,位于需要注意的是函数默认返回 None, 对于一个未知的类型应该引发 TypeError 异常,一个典型的结构如下:

Python
def default(obj):
    if isinstance(obj, decimal.Decimal):
        return str(obj)
    if isinstance(obj, DataFrame):
        ...
    raise TypeError