You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python类对象序列化/反序列化选json还是pickle?如何实现?

选型建议

优先选择JSON库,理由如下:

  • 你的设备属性(字符串、整数、浮点数列表)均为JSON原生支持的类型,适配成本极低
  • JSON为纯文本格式,可直接打开查看内容,排查问题更方便
  • 无安全风险,跨语言跨平台兼容性好,后续如果要用其他语言读取数据也不需要额外转换

如果后续你的unit_log类会加入Python专属属性(比如函数引用、其他自定义类的嵌套对象),再考虑使用pickle库,pickle可以直接序列化整个类实例,不需要手动做格式转换,但缺点是生成的是二进制文件不可读,仅支持Python环境使用,加载来源不明的pickle文件存在执行恶意代码的安全风险。

完整功能实现(JSON版本)

修改你的file.py代码如下:

import json
import os

class unit_log:
    # 类属性:存储所有设备实例
    units = {}
    # 数据存储路径,可自行修改
    DATA_FILE = "unit_logs.json"

    def __init__(self, serial_number):
        self.serial_number = serial_number
        self.unit_name = f'unit_{serial_number}'
        self.status = 'Open'
        self.offsets = []
        self.folder = f'C:\\Users\\Thomas\\Documents\\{serial_number}'
        # 新建实例自动加入全局存储
        unit_log.units[self.unit_name] = self
        # 同步到模块全局变量,支持直接用unit_1这种方式访问
        globals()[self.unit_name] = self

    @classmethod
    def load(cls):
        # 不存在数据文件时直接返回
        if not os.path.exists(cls.DATA_FILE):
            return
        with open(cls.DATA_FILE, 'r', encoding='utf-8') as f:
            data = json.load(f)
        # 清空旧实例避免冲突
        cls.units.clear()
        # 遍历存储数据生成类实例
        for unit_data in data.values():
            unit = cls(unit_data['serial_number'])
            # 覆盖默认属性为存储的属性值
            unit.status = unit_data['status']
            unit.offsets = unit_data['offsets']
            unit.folder = unit_data['folder']

    @classmethod
    def save(cls):
        # 把所有实例转换为可序列化的字典
        data = {}
        for unit_name, unit in cls.units.items():
            data[unit_name] = {
                "unit_name": unit.unit_name,
                "serial_number": unit.serial_number,
                "status": unit.status,
                "offsets": unit.offsets,
                "folder": unit.folder
            }
        # 写入JSON文件
        with open(cls.DATA_FILE, 'w', encoding='utf-8') as f:
            json.dump(data, f, indent=4, ensure_ascii=False)
使用方法

和你要求的操作逻辑完全一致:

  1. 加载已有数据
from file import unit_log
unit_log.load()
  1. 访问已有设备
print(unit_1.serial_number)
# 输出 1
  1. 修改设备属性
unit_1.status = 'Closed'
unit_1.offsets.append(0.02)
  1. 新增设备
unit_2 = unit_log(2)
  1. 保存所有修改到文件
unit_log.save()
可选:pickle版本实现(更简洁)

如果你不需要可读的文本格式,pickle版本不需要手动做属性转换,代码更简单:

import pickle
import os

class unit_log:
    units = {}
    DATA_FILE = "unit_logs.pkl"

    def __init__(self, serial_number):
        self.serial_number = serial_number
        self.unit_name = f'unit_{serial_number}'
        self.status = 'Open'
        self.offsets = []
        self.folder = f'C:\\Users\\Thomas\\Documents\\{serial_number}'
        unit_log.units[self.unit_name] = self
        globals()[self.unit_name] = self

    @classmethod
    def load(cls):
        if not os.path.exists(cls.DATA_FILE):
            return
        with open(cls.DATA_FILE, 'rb') as f:
            cls.units = pickle.load(f)
        # 同步实例到全局变量
        for unit_name, unit in cls.units.items():
            globals()[unit_name] = unit

    @classmethod
    def save(cls):
        with open(cls.DATA_FILE, 'wb') as f:
            pickle.dump(cls.units, f)

使用方法和JSON版本完全相同。

内容的提问来源于stack exchange,提问作者Thomas K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 03:21:03