如何将一个 class pickle, 在缺失源码的情况下也能 unpickle 后生成实例

查看 22|回复 0
作者:justou   
我用一些伪代码来说明这个问题, 假设有如下目录结构
├── main.py
├── media
│   ├── __init__.py
│   ├── ....
│   └── media.py
└── player
    ├── __init__.py
    ├── ....
    └── player.py
main.py 中:
from media.media import Media
from player.player import Player
p = Player()
m = Media()
p(m)
Media, Player的实现依赖于很多自己写的模块以及第三方模块的类和函数, 想把Media和Player类 pickle 到文件,
with open('media.pkl', 'wb') as f, open('player.pkl', 'wb') as g:
        my_super_pickle.dump(Media, f)
        my_super_pickle.dump(Player, g)
缺失源码情况下也能 unpickle 出完整的类用于生成实例正常使用:
# 没有以上实现源码, 只有 media.pkl, 'player.pkl' 和第三方依赖的 python 环境
with open('media.pkl', 'rb') as f, open('player.pkl', 'rb') as g:
        Media = my_super_pickle.load(f)
        Player = my_super_pickle.load(g)
   
p = Player()
m = Media()
p(m)
所以my_super_pickle 需要将项目下与 Media 和 Player 所有相关的依赖都以某种方式 pickle, 且忽略掉不在该目录下的第三方依赖.
  • 如果使用标准库的 pickle, pickle.dump(Media, f), 结果只有一条 import 语句from media.media import Media, 所以依赖于源码和原来的目录结构.
  • 使用一些工具库如: dill, cloudpickle 可以将 Media 的源码 pickle,但是无法将 Media 实现所有依赖的类也同时 pickle, 这跟直接用inspect.getsource得到源码然后用标准库的 pickle 又有什么区别呢?

    目的: 发布一些自带源码的数据包, 数据包中的数据是主角, 源码是解释数据的手段. 在后续源码更新后, 旧的数据包也能正常使用——旧的数据和旧的源码绑定在一起,新的数据跟新的源码绑定在一起.
    请问各位有什么好的解决方案?
  • 您需要登录后才可以回帖 登录 | 立即注册

    返回顶部