目录
pickle:
Python 中的pickle 是一个内置模块,用于序列化和反序列化 Python 对象结构。序列化是将对象转换成字节流的过程,这样对象就可以被存储到文件中或者通过网络传输。反序列化则是将这些字节流重新转换成原始对象的过程。
json:
json模块是 Python 中用于处理 JSON 数据格式的内置模块。JSON(JavaScript Object Notation)是一种文本格式,用于在不同系统之间传输数据。它基于 JavaScript 的对象和数组表示,但已经被许多编程语言支持,包括 Python。
问题引入:
使用 pickle 模块序列化和反序列化
使用 json 模块序列化和反序列化
pickle用法:
语法概览
示例
序列化(Pickle)
json的用法
语法概览
示例
pickle:
Python 中的pickle 是一个内置模块,用于序列化和反序列化 Python 对象结构。序列化是将对象转换成字节流的过程,这样对象就可以被存储到文件中或者通过网络传输。反序列化则是将这些字节流重新转换成原始对象的过程。
json:
json模块是 Python 中用于处理 JSON 数据格式的内置模块。JSON(JavaScript Object Notation)是一种文本格式,用于在不同系统之间传输数据。它基于 JavaScript 的对象和数组表示,但已经被许多编程语言支持,包括 Python。
问题引入:
# define a dict object
obj={
"name":"Bonnie",
"isAGirl":True,
"age":22,
"hobbies":["guitar","singing","traveling"]
"ss":None
}
# 将obj写入已打开的二进制文件,序列化
f =open("test.txt","w")
f.write(obj)
报错:
Traceback (most recent call last):
File "E:\桌面\计算机\全栈\django\django项目\untitled1\ll.py", line 10, in <module>
f.write(obj)
TypeError: write() argument must be str, not dict
原因:
在 Python 中,不能直接使用 write 方法将字典对象写入文件,因为 write 方法只能处理字符串或字节序列。要将字典对象序列化并写入文件,你需要使用 pickle 模块。以下是如何使用 pickle 模块将字典对象序列化并写入文件的正确方式:
python
import pickle
# 定义一个字典对象
obj = {
"name": "Bonnie",
"isAGirl": True,
"age": 22,
"hobbies": ["guitar", "singing", "traveling"]
}
# 使用 'wb' 模式打开文件,以便写入二进制数据
with open("test.pkl", "wb") as f:
# 使用 pickle.dump 将对象序列化并写入文件
pickle.dump(obj, f)
请注意以下几点:
- 文件模式应为 'wb',表示以二进制写入模式打开文件。
- 使用 pickle.dump 而不是 f.write 来序列化对象并写入文件。
- 我将文件扩展名从 .txt 改为 .pkl,以表明这是一个使用 pickle 模块序列化的文件。
如果你想要从这个文件中读取并反序列化对象,可以使用以下代码:
python
# 使用 'rb' 模式打开文件,以便读取二进制数据
with open("test.pkl", "rb") as f:
# 使用 pickle.load 从文件中读取并反序列化对象
loaded_obj = pickle.load(f)
print(loaded_obj)
这将输出原始字典对象。
那问题json处理可以吗?
让我们通过一个例子来比较 pickle 和 json 模块在处理 Python 中特殊数据类型时的不同。
首先,我们定义一个包含 Python 特殊数据类型和自定义对象的复杂数据结构:
python
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# 创建一个包含特殊数据类型和自定义对象的字典
complex_obj = {
"name": "Bonnie",
"is_girl": True,
"age": 22,
"hobbies": ["guitar", "singing", "traveling"],
"nothing": None,
"bytes_data": b"byte data",
"person": Person("Bonnie", 22)
}
使用 pickle 模块序列化和反序列化
使用 pickle 可以轻松地序列化和反序列化上述包含特殊数据类型的复杂对象:
python
import pickle
# 使用 pickle 序列化对象
with open('complex_obj.pkl', 'wb') as f:
pickle.dump(complex_obj, f)
# 使用 pickle 反序列化对象
with open('complex_obj.pkl', 'rb') as f:
loaded_obj = pickle.load(f)
print(loaded_obj)
pickle 模块能够处理 None、bytes 类型以及自定义对象 Person,并且能够保持对象的结构和类型。
使用 json 模块序列化和反序列化
当我们尝试使用 json 模块来序列化相同的对象时,会遇到问题:
python
import json
# 尝试使用 json 序列化对象
try:
json_string = json.dumps(complex_obj)
except TypeError as e:
print("JSON serialization error:", e)
这段代码会抛出一个 TypeError,因为 json.dumps() 无法处理 None 类型、bytes 类型和自定义对象 Person。为了能够使用 json 序列化,我们需要定义一个自定义的序列化函数来处理这些特殊类型:
python
def my_encoder(obj):
if isinstance(obj, bytes):
return obj.decode('utf-8') # 假设 bytes 对象是 UTF-8 编码的字符串
raise TypeError(f"Object of type '{obj.__class__.__name__}' is not JSON serializable")
# 使用自定义的序列化函数
json_string = json.dumps(complex_obj, default=my_encoder)
# 将 JSON 字符串写入文件
with open('complex_obj.json', 'w') as f:
f.write(json_string)
# 反序列化时,我们失去了类型信息,只能得到一个普通的字典
loaded_obj_json = json.loads(json_string)
print(loaded_obj_json)
在这个例子中,我们定义了一个 my_encoder 函数来处理 bytes 类型,将其解码为字符串。但是,对于 None 类型和自定义对象 Person,我们仍然无法直接序列化。即使对于 bytes,我们也失去了原始的二进制数据,因为它被解码为了字符串。
通过这个例子,你可以看到 pickle 和 json 在处理特殊数据类型时的不同。pickle 更加灵活,能够处理几乎所有的 Python 对象,而 json 则更加通用和安全,但需要处理一些数据类型的兼容性问题。
pickle用法:
语法概览
Pickle 提供了几个函数来处理序列化和反序列化:
- pickle.dump(obj, file, protocol=None, *, fix_imports=True): 将对象 obj 序列化并写入到文件对象 file 中。
- pickle.dumps(obj, protocol=None, *, fix_imports=True): 将对象 obj 序列化并返回一个字节串。
- pickle.load(file, *, fix_imports=True, encoding="ASCII", errors="strict"): 从文件对象 file 中读取字节流并反序列化成 Python 对象。
- pickle.loads(bytes_object, *, fix_imports=True): 从字节串 bytes_object 中读取字节流并反序列化成 Python 对象。
其中,protocol 参数决定了使用的序列化协议版本,可以是以下之一:
- pickle.HIGHEST_PROTOCOL: 使用最高的协议版本。
- pickle.DEFAULT_PROTOCOL: 使用默认的协议版本。
- 0: 表示原始协议。
- 1: 表示文本模式。
- 2: 表示二进制模式,更高效。
示例
序列化(Pickle)
import pickle
data = {'name': 'Alice', 'age': 30, 'city': 'New York'}
# 使用pickle.dumps将字典对象序列化为字节流
serialized_data = pickle.dumps(data)
# 使用pickle.loads将字节流反序列化为原始对象
deserialized_data = pickle.loads(serialized_data)
print(deserialized_data)
# 输出: {'name': 'Alice', 'age': 30, 'city': 'New York'}
# 使用pickle.dump将字典对象序列化并写入文件
with open('data.pickle', 'wb') as file:
pickle.dump(data, file)
# 使用pickle.load从文件中读取字节流并反序列化为原始对象
with open('data.pickle', 'rb') as file:
loaded_data = pickle.load(file)
print(loaded_data)
# 输出: {'name': 'Alice', 'age': 30, 'city': 'New York'}
json的用法
语法概览
json模块中的主要函数和方法如下:
- `json.dumps(obj, indent=None)`
将Python对象`obj`编码为JSON格式的字符串,并返回结果。如果指定了`indent`参数,它将定义缩进的级别,使得生成的JSON字符串具有更好的可读性。
- `json.loads(json_str)`
将JSON格式的字符串`json_str`解码为Python对象,并返回结果。
- `json.dump(obj, file, indent=None)`
将Python对象`obj`编码为JSON格式的字符串,并将结果写入文件对象`file`中。如果指定了`indent`参数,它将定义缩进的级别。
- `json.load(file)`
从文件对象`file`中读取JSON格式的字符串,并将其解码为Python对象。
示例
下面是一个简单的示例,演示如何使用json模块进行编码和解码:
import json
data = {'name': 'Alice', 'age': 30, 'city': 'New York'}
# 将Python对象编码为JSON字符串
json_str = json.dumps(data)
print(json_str)
# 输出: {"name": "Alice", "age": 30, "city": "New York"}
# 将JSON字符串解码为Python对象
decoded_data = json.loads(json_str)
print(decoded_data)
# 输出: {'name': 'Alice', 'age': 30, 'city': 'New York'}
# 将Python对象编码为JSON字符串,并写入文件
with open('data.json', 'w') as file:
json.dump(data, file)
# 从文件中读取JSON字符串,并解码为Python对象
with open('data.json', 'r') as file:
loaded_data = json.load(file)
print(loaded_data)
# 输出: {'name': 'Alice', 'age': 30, 'city': 'New York'}
需要注意的是,JSON只支持一些基本数据类型,如字符串、数字、布尔值、列表、字典和None。Python对象中的其他类型,如函数、类实例和特殊对象,可能无法直接转换为JSON字符串。可以使用`json.dump()`和`json.load()`函数配合自定义的编码和解码函数来处理这些特殊类型的对象。此外,json模块还提供了格式化输出、排序键、编码和解码的扩展选项,可以根据具体需求进行配置。