python中的pickle模块和json模块

目录

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)

请注意以下几点:

  1. 文件模式应为 'wb',表示以二进制写入模式打开文件。
  2. 使用 pickle.dump 而不是 f.write 来序列化对象并写入文件。
  3. 我将文件扩展名从 .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模块还提供了格式化输出、排序键、编码和解码的扩展选项,可以根据具体需求进行配置。

相关推荐

  1. pythonpickle模块json模块

    2024-07-14 06:08:03       24 阅读
  2. python入门:常用模块json&pickle模块

    2024-07-14 06:08:03       40 阅读
  3. Python 常用模块pickle

    2024-07-14 06:08:03       41 阅读
  4. python模块json

    2024-07-14 06:08:03       63 阅读
  5. python模块

    2024-07-14 06:08:03       47 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-14 06:08:03       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-14 06:08:03       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-14 06:08:03       58 阅读
  4. Python语言-面向对象

    2024-07-14 06:08:03       69 阅读

热门阅读

  1. ClickHouse实战第二章-ClickHouse 的安装调试

    2024-07-14 06:08:03       25 阅读
  2. Spring事件监听机制详解

    2024-07-14 06:08:03       22 阅读
  3. 案例:分库分表与SELECT * 发生的线上问题

    2024-07-14 06:08:03       24 阅读
  4. TypeScript的类型谓词与控制流分析

    2024-07-14 06:08:03       26 阅读
  5. ThreadLocal详解

    2024-07-14 06:08:03       22 阅读
  6. 小程序如何刷新当前页面

    2024-07-14 06:08:03       25 阅读
  7. qt 根据名称获取按钮,并添加点击事件

    2024-07-14 06:08:03       19 阅读
  8. Linux开发讲课37--- ARM的22个常用概念

    2024-07-14 06:08:03       27 阅读
  9. VMware 虚拟机 Windows 系统卡顿解决

    2024-07-14 06:08:03       23 阅读