如何使用dill/pickle保存加载作为全局变量容器的Python模块
原有代码问题说明
- 读取pickle文件时使用了文本模式
'r',序列化和反序列化都需要用二进制模式(wb/rb),否则会直接触发编码或格式错误 - 直接序列化模块的整个
__dict__会包含大量内置特殊属性(如__name__、__spec__、__loader__等),这类属性大多不可序列化,反序列化后直接覆盖模块__dict__会破坏模块结构,触发类型错误
正确实现方案
dill原生支持模块对象序列化,不需要单独提取__dict__,可以直接序列化整个模块,恢复时只同步自定义变量即可,不会破坏模块本身的结构,同时完全适配你用模块做多线程全局变量共享的需求:
import dill import res # 保存模块状态 with open("test.pkl", 'wb') as pickle_file: dill.dump(res, pickle_file) # 测试修改变量 res.VAR1 = "123" print(res.VAR1) # 输出 123 # 恢复模块状态 with open("test.pkl", 'rb') as pickle_file: loaded_res = dill.load(pickle_file) # 仅同步自定义变量,不覆盖模块内置属性 for attr_name, attr_val in loaded_res.__dict__.items(): # 过滤双下划线开头的内置属性 if not attr_name.startswith("__"): setattr(res, attr_name, attr_val) print(res.VAR1) # 输出初始值 asd
如果需要更轻量化的存储,可以只序列化自定义变量:
import dill import res # 保存时仅提取自定义变量 module_state = {k:v for k, v in res.__dict__.items() if not k.startswith("__")} with open("test.pkl", 'wb') as pickle_file: dill.dump(module_state, pickle_file) # 恢复变量 with open("test.pkl", 'rb') as pickle_file: module_state = dill.load(pickle_file) for k, v in module_state.items(): setattr(res, k, v)
内容的提问来源于stack exchange,提问作者NiBa
相关产品推荐
相关产品推荐

