Python标准库json模块和pickle模块使用详解

1. 简介

Python是一种高级语言,有许多对外部IO格式的支持,其中最为常用的两个是: JSON和Pickling; JSON 和 Pickling都是用于序列化数据结构的模块,用于将 Python 数据结构转换为基于 utf-8 编码的字符串; 在传输这些字符串给受信任方时,受信方可以通过相反的序列化过程来重新得到它们。

2. JSON(JavaScript Object Notation)

JSON是一种轻量级数据交换格式,表示为键值对的集合,数据使用逗号分隔,花括号括起来; JSON文件主要由两个结构组成:键值对和数组,其中键值对类似于Python中的字典,用花括号括起来,数组类似于Python中的列表,用方括号括起来。

2.1 JSON在Python中的使用

JSON在Python中得以支持是因为标准库中内置了json模块的支持。

JSON与Python之间的转换,有如下函数:

json.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)

json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True,allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)

json.loads(s, *, cls=None, object_hook=None, parse_float=None,parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

json.load(fp, *, cls=None, object_hook=None, parse_float=None,parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

举个例子,我们可以使用json.dumps()将Python数据结构转换为JSON格式字符串,并用json.loads()函数将JSON格式字符串转换回Python数据结构:

import json

car = {

"make": "Ford",

"model": "Mustang",

"year": 1964

}

print(json.dumps(car))

// 输出:{"make": "Ford", "model": "Mustang", "year": 1964}

car1 = json.loads(json.dumps(car))

print(car1 == car)

// 输出:True

2.2 JSON参数

以下是json模块中熟悉的一些参数:

skipkeys: bool, 当某个不是str的类型被作为键时,跳过该键(如果该可选参数未指定,默认值为 False,会引发 TypeError);

ensure_ascii: bool, 控制是否将非 ASCII 编码的字符输出为 ASCII 编码的 JSON 字符串(如果该可选项未指定,默认值为 True,会转义所有非 ASCII 字符);

check_circular: bool, 指示仅适用于json.JSONEncoder子类的参数;如果指定为False,则编码器将出现循环引用,并引发一个 ValueError (默认为True);

allow_nan: bool, 允许编码器为 NaN 和 Infinity 编码。

3. Pickle

pickle模块是Python标准模块之一,用于在Python对象之间进行序列化和反序列化。在序列化过程中,Python数据结构被转换为字节流,称为pickled,只有通过反序列化才能再次转换回原始数据结构。

3.1 Pickle的使用

Python内置了pickle模块,类似于json模块,它提供了一些基本的接口来序列化和反序列化Python对象,如下所示:

pickle.dump(obj, file, protocol=None, *, fix_imports=True)

pickle.dumps(obj, protocol=None, *, fix_imports=True)

pickle.load(file, *, fix_imports=True, encoding='ASCII', errors='strict',buffer_callback=None)

pickle.loads(bytes_object, *, fix_imports=True, encoding='ASCII', errors='strict', buffer_callback=None)

举个例子,我们可以使用pickle.dumps()将Python数据结构转换为字节流,以便存储在文件或数据库中,并使用pickle.loads()函数将pickled数据流反序列化:

import pickle

car = {

"make": "Ford",

"model": "Mustang",

"year": 1964

}

pickled = pickle.dumps(car)

print(pickled)

car1 = pickle.loads(pickled)

print(car1 == car)

// 输出:True

3.2 Pickle安全性问题

在应用pickle时,重要的安全性问题需要权衡其带来的影响,因为反序列化可以在不知不觉中注入任意代码,这是pickle存在的主要问题。所以,pickle的使用应该受到诸如不在不受信任的来源中使用,否则很容易遇到安全问题。pickle不能保证将所有的Python对象序列化成文件,其中包括内部对象、文件对象、套接字等等。一些Python类不能被序列化,more it’s a binary format that is very fragile: there is no version machanism built in to evolve the format over time.

4. 总结

JSON和pickle模块都是Python序列化的重要方法,json主要是将Python数据转换为一个JSON字符串,而pickle是将Python数据转换为一个二进制流,这两个模块的使用都相对简单,我们可以根据自己的需求选择合适的模块。但是,我们也要注意到pickle存在的安全性问题。

后端开发标签