python - 带有 dill 的模块中的 Pickle 类定义

标签 python python-3.x serialization pickle dill

我的模块包含一个应该是 pickleable 的类,包括实例和定义 我有以下结构:

MyModule
|-Submodule
  |-MyClass

在关于 SO 的其他问题中,我已经发现 dill 能够 pickle 类定义,并且通过将 MyClass 的定义复制到一个单独的脚本中并在那里 pickle 它肯定足够了,就像这样:

import dill as pickle

class MyClass(object):
    ...

instance = MyClass(...)
with open(..., 'wb') as file:
   pickle.dump(instance, file)

但是,导入类时不起作用:

pickle :

from MyModule.Submodule import MyClass
import dill as pickle

instance = MyClass(...)
with open(.., 'wb') as file:
    pickle.dump(instance, file)

正在加载:

import dill as pickle

with open(..., 'rb') as file:
    instance = pickle.load(file)

>>> ModuleNotFoundError: No module named 'MyModule'

我认为类定义是通过引用保存的,尽管它不应该按照 dill 中的默认设置。当 MyClass 被称为 __main__.MyClass 时,这是正确完成的,当在主脚本中定义类时会发生这种情况。

我想知道,有什么方法可以将 MyClassMyModule 中分离出来?有什么方法可以使它像顶级导入 (__main__.MyClass) 这样 dill 知道如何将它加载到我的另一台机器上?

相关问题: Why dill dumps external classes by reference no matter what

最佳答案

Dill 确实只在 __main__ 中存储对象的定义,而不是模块中的对象定义,因此解决此问题的一种方法是在 main 中重新定义这些对象:

def mainify(obj):
    import __main__
    import inspect
    import ast

    s = inspect.getsource(obj)
    m = ast.parse(s)
    co = compile(m, '<string>', 'exec')
    exec(co, __main__.__dict__)

然后:

from MyModule.Submodule import MyClass
import dill as pickle

mainify(MyClass)
instance = MyClass(...)
with open(.., 'wb') as file:
    pickle.dump(instance, file)

现在您应该能够从任何地方加载 pickle,即使 MyModule.Submodule 不可用。

关于python - 带有 dill 的模块中的 Pickle 类定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52402783/

相关文章:

java - readObject() 在特定对象上阻塞

python - 如何删除文件中不同样式的行(都是str格式)?

Python 无法处理以 0 开头的数字字符串。为什么?

jQuery UI Sortable - 单击按钮时保存顺序

Python - 更改列表中的项目值

Python:导入 urllib.quote

c# - 为什么 BinaryFormatter 试图在可序列化类上序列化事件?

python - 使用 boto + Python 上传 Amazon S3 失败

python - 如何用Qt设计倒计时

python - 在 Keras 中训练多元回归模型时损失值非常大