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存在的安全性问题。