Python Pickle 与 JSON 序列化详解:存储、反序列化与对比

Python Pickle 与 JSON 序列化详解:存储、反序列化与对比

文章目录

  • [Python Pickle 与 JSON 序列化详解:存储、反序列化与对比](#Python Pickle 与 JSON 序列化详解:存储、反序列化与对比)
      • [一 功能总览](#一 功能总览)
      • [二 Pickle](#二 Pickle)
      • [三 Json](#三 Json)
        • [1 应用](#1 应用)
        • [2 序列化](#2 序列化)
        • [3 反序列化](#3 反序列化)
        • [4 不能序列化 class 类](#4 不能序列化 class 类)
      • [四 Pickle 和 Json 对比](#四 Pickle 和 Json 对比)
      • [五 完整代码示例](#五 完整代码示例)
      • [六 源码地址](#六 源码地址)

在 Python 中,序列化是保存数据和对象的重要方式,其中 Pickle 和 JSON 是常用的两种序列化方法。本文详细介绍了如何使用 Pickle 和 JSON 进行数据和类的序列化与反序列化操作。通过 Pickle,能够将 Python 对象保存为二进制文件,而 JSON 更适用于跨语言的数据交换。文章包含了 Pickle 的序列化、反序列化,以及如何处理系统资源对象。还涵盖了 JSON 的基本操作及其与 Pickle 的对比,帮助开发者根据不同场景选择合适的序列化方式。

一 功能总览

Pickle Json
pickle.dumps() json.dumps()
pickle.dump() json.dump()
pickle.load() json.load()

二 Pickle

1 应用

使用 pickle 去 dumps 数据

python 复制代码
		# import pickle	
		data = {"filename": "f1.txt", "create_time": "today", "size": 111}
		print(pickle.dumps(data))
2 序列化

将数据转换成文件储存

python 复制代码
    # 用 pickle.dump() 将字典直接转换成一个文件。
    data = {"filename": "f1.txt", "create_time": "today", "size": 111}
    with open("data.pkl", "wb") as f:
        pickle.dump(data, f)
    print(os.listdir())

    with open("data.pkl", "rb") as f:
        data = pickle.load(f)
    print(data)
3 反序列化

pickle 可以将 类打包成文件,然后 unpickle 还原回来,File 类

python 复制代码
class File:
    def __init__(self, name, create_time, size):
        self.name = name
        self.create_time = create_time
        self.size = size

    def change_name(self, new_name):
        self.name = new_name

从 data.pkl 文件中 反序列化回来

python 复制代码
    # 打包类,File类
    data = File("f2.txt", "now", 222)
    # 存
    with open("data.pkl", "wb") as f:
        pickle.dump(data, f)
    # 读
    with open("data.pkl", "rb") as f:
        read_data = pickle.load(f)
    print(read_data.name)
    print(read_data.size)
4 系统资源对象
1)不能被序列化的系统资源对象

注:依赖外部系统状态的对象不能被序列化,比如 打开文件,网络连接,线程,进程,栈帧等等。

python 复制代码
class File02:
    def __init__(self, name, create_time, size):
        self.name = name
        self.create_time = create_time
        self.size = size
        # 打开文件
        self.file = open(name, "w")

    # 依赖外部系统状态的对象不能被序列化,比如 打开的文件,网络连接,线程,进程,栈帧等等。
    # data = File02("f3.txt", "now", 222)
    # pickle 存,会报错
    # TypeError: cannot pickle '_io.TextIOWrapper' object
    # with open("data.pkl", "wb") as f:
    #     pickle.dump(data, f)
2)强行序列化系统资源对象

硬要用依赖外部系统状态的对象去 pickle 保存,可以规避一下,看 类 File03

python 复制代码
class File03:
    def __init__(self, name, create_time, size):
        self.name = name
        self.create_time = create_time
        self.size = size
        self.file = open(name, "w")

    def __getstate__(self):
        # pickle 出去需要且能被 pickle 的信息
        pickled = {"name": self.name, "create_time": self.create_time, "size": self.size}
        return pickled

    def __setstate__(self, pickled_dict):
        # unpickle 加载回来,重组 class
        self.__init__(
            pickled_dict["name"], pickled_dict["create_time"], pickled_dict["size"])

示例

python 复制代码
 # 硬要用依赖外部系统状态的对象去 pickle 保存,可以规避一下
    # pickle.dump() 会调用 __getstate__() 获取序列化的对象。 __setstate__() 在反序列化时被调用。

    data = File03("f3.txt", "now", 222)
    # 存
    with open("data.pkl", "wb") as f:
        pickle.dump(data, f)
    # 读
    with open("data.pkl", "rb") as f:
        read_data = pickle.load(f)
    print(read_data.name)
    print(read_data.size)
    print()

三 Json

1 应用
python 复制代码
# Json
# import json
data = {"filename": "f1.txt", "create_time": "today", "size": 111}
j = json.dumps(data)
print(j)
print(type(j))
2 序列化

Json 储存数据

python 复制代码
# Json 储存数据
data = {"filename": "f1.txt", "create_time": "today", "size": 111}
with open("data.json", "w") as f:
    json.dump(data, f)

print("直接当纯文本读:")
with open("data.json", "r") as f:
    print(f.read())
3 反序列化
python 复制代码
print("用 json 加载了读:")
with open("data.json", "r") as f:
    new_data = json.load(f)
print("字典读取:", new_data["filename"])
4 不能序列化 class 类
python 复制代码
class File04:
    def __init__(self, name, create_time, size):
        self.name = name
        self.create_time = create_time
        self.size = size

    def change_name(self, new_name):
        self.name = new_name
#  json 不能序列化保存 class
# TypeError: Object of type File is not JSON serializable
data = File04("f4.txt", "now", 222)
# 存,会报错
# with open("data.json", "w") as f:
#     json.dump(data, f)

四 Pickle 和 Json 对比

对比 Pickle Json
存储格式 Python 特定的 Bytes 格式 通用 JSON text 格式,可用于常用的网络通讯中
数据种类 类,功能,字典,列表,元组等 基本和 Pickle 一样,但不能存类,功能
保存后可读性 不能直接阅读 能直接阅读
跨语言性 只能用在 Python 可以跨多语言读写
处理时间 长(需编码数据) 短(不需编码)
安全性 不安全(除非你信任数据源) 相对安全

五 完整代码示例

python 复制代码
# This is a sample Python script.

# Press ⌃R to execute it or replace it with your code.
# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings.
import pickle
import os
import json


class File04:
    def __init__(self, name, create_time, size):
        self.name = name
        self.create_time = create_time
        self.size = size

    def change_name(self, new_name):
        self.name = new_name


class File03:
    def __init__(self, name, create_time, size):
        self.name = name
        self.create_time = create_time
        self.size = size
        self.file = open(name, "w")

    def __getstate__(self):
        # pickle 出去需要且能被 pickle 的信息
        pickled = {"name": self.name, "create_time": self.create_time, "size": self.size}
        return pickled

    def __setstate__(self, pickled_dict):
        # unpickle 加载回来,重组 class
        self.__init__(
            pickled_dict["name"], pickled_dict["create_time"], pickled_dict["size"])


class File02:
    def __init__(self, name, create_time, size):
        self.name = name
        self.create_time = create_time
        self.size = size
        self.file = open(name, "w")


class File:
    def __init__(self, name, create_time, size):
        self.name = name
        self.create_time = create_time
        self.size = size

    def change_name(self, new_name):
        self.name = new_name


def print_hi(name):
    # Use a breakpoint in the code line below to debug your script.
    print(f'Hi, {name}')  # Press ⌘F8 to toggle the breakpoint.
    # 主要涉及到的功能
    # Pickle
    # pickle.dumps()
    # pickle.dump()
    # pickle.load()
    # Json
    # json.dumps()
    # json.dump()
    # json.load()
    data = {"filename": "f1.txt", "create_time": "today", "size": 111}
    print(pickle.dumps(data))
    # 用 pickle.dump() 将字典直接转换成一个文件。
    data = {"filename": "f1.txt", "create_time": "today", "size": 111}
    with open("data.pkl", "wb") as f:
        pickle.dump(data, f)
    print(os.listdir())

    with open("data.pkl", "rb") as f:
        data = pickle.load(f)
    print(data)

    # 打包类,File类
    data = File("f2.txt", "now", 222)
    # 存
    with open("data.pkl", "wb") as f:
        pickle.dump(data, f)
    # 读
    with open("data.pkl", "rb") as f:
        read_data = pickle.load(f)
    print(read_data.name)
    print(read_data.size)

    # 依赖外部系统状态的对象不能被序列化,比如 打开的文件,网络连接,线程,进程,栈帧等等。
    # data = File02("f3.txt", "now", 222)
    # pickle 存,会报错
    # TypeError: cannot pickle '_io.TextIOWrapper' object
    # with open("data.pkl", "wb") as f:
    #     pickle.dump(data, f)

    # 硬要用依赖外部系统状态的对象去 pickle 保存,可以规避一下
    # pickle.dump() 会调用 __getstate__() 获取序列化的对象。 __setstate__() 在反序列化时被调用。

    data = File03("f3.txt", "now", 222)
    # 存
    with open("data.pkl", "wb") as f:
        pickle.dump(data, f)
    # 读
    with open("data.pkl", "rb") as f:
        read_data = pickle.load(f)
    print(read_data.name)
    print(read_data.size)
    print()

    # Json
    data = {"filename": "f1.txt", "create_time": "today", "size": 111}
    j = json.dumps(data)
    print(j)
    print(type(j))
    print()

    # Json 储存数据
    data = {"filename": "f1.txt", "create_time": "today", "size": 111}
    with open("data.json", "w") as f:
        json.dump(data, f)

    print("直接当纯文本读:")
    with open("data.json", "r") as f:
        print(f.read())

    print("用 json 加载了读:")
    with open("data.json", "r") as f:
        new_data = json.load(f)
    print("字典读取:", new_data["filename"])
    print()
    #  json 不能序列化保存 class
    # TypeError: Object of type File is not JSON serializable
    data = File04("f4.txt", "now", 222)
    # 存,会报错
    # with open("data.json", "w") as f:
    #     json.dump(data, f)

    # Pickle 和 Json 的不同
    # 存储格式  Python 特定的 Bytes 格式   通用 JSON text 格式,可用于常用的网络通讯中
    # 数据种类  类,功能,字典,列表,元组等  基本和 Pickle 一样,但不能存类,功能
    # 保存后可读性  不能直接阅读  能直接阅读
    # 跨语言性  只能用在 Python  可以跨多语言读写
    # 处理时间  长(需编码数据)  短(不需编码)
    # 安全性  不安全(除非你信任数据源) 相对安全


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    print_hi('pickle 和 json 序列化')

# See PyCharm help at https://www.jetbrains.com/help/pycharm/

复制粘贴并覆盖到你的 main.py 中运行,运行结果如下。

nginx 复制代码
Hi, pickle 和 json 序列化
b'\x80\x04\x958\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x08filename\x94\x8c\x06f1.txt\x94\x8c\x0bcreate_time\x94\x8c\x05today\x94\x8c\x04size\x94Kou.'
['new_file4.txt', 'Function 函数.py', 'new_file5.txt', '如何控制异常 try-except.py', 'new_file.txt', 'me.py', 'new_file2.txt', '.DS_Store', 'new_file3.txt', 'f3.txt', 'Module 模块.py', 'chinese.txt', 'no_file.txt', 'module', 'user', '数据种类.py', '__pycache__', 'data.json', 'project', '正则表达式.py', 'file.py', '单元测试.py', 'pickle 和 json序列化.py', '变量与运算.py', 'data.pkl', '文件目录管理.py', '条件判断.py', 'Class 类.py', 'main.py', '读写文件.py', 'for 和 while 循环.py', '.idea']
{'filename': 'f1.txt', 'create_time': 'today', 'size': 111}
f2.txt
222
f3.txt
222

{"filename": "f1.txt", "create_time": "today", "size": 111}
<class 'str'>

直接当纯文本读:
{"filename": "f1.txt", "create_time": "today", "size": 111}
用 json 加载了读:
字典读取: f1.txt

六 源码地址

代码地址:

国内看 Giteepickle 和 json序列化.py

国外看 GitHubpickle 和 json序列化.py

引用 莫烦 Python

相关推荐
花酒锄作田1 天前
使用 pkgutil 实现动态插件系统
python
前端付豪1 天前
LangChain链 写一篇完美推文?用SequencialChain链接不同的组件
人工智能·python·langchain
曲幽1 天前
FastAPI实战:打造本地文生图接口,ollama+diffusers让AI绘画更听话
python·fastapi·web·cors·diffusers·lcm·ollama·dreamshaper8·txt2img
老赵全栈实战1 天前
Pydantic配置管理最佳实践(一)
python
阿尔的代码屋1 天前
[大模型实战 07] 基于 LlamaIndex ReAct 框架手搓全自动博客监控 Agent
人工智能·python
AI探索者2 天前
LangGraph StateGraph 实战:状态机聊天机器人构建指南
python
AI探索者2 天前
LangGraph 入门:构建带记忆功能的天气查询 Agent
python
FishCoderh2 天前
Python自动化办公实战:批量重命名文件,告别手动操作
python
躺平大鹅2 天前
Python函数入门详解(定义+调用+参数)
python
曲幽2 天前
我用FastAPI接ollama大模型,差点被asyncio整崩溃(附对话窗口实战)
python·fastapi·web·async·httpx·asyncio·ollama