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

vri*_*ael 8 python serialization pickle python-3.x dill

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

MyModule
|-Submodule
  |-MyClass
Run Code Online (Sandbox Code Playgroud)

在关于 SO 的其他问题中,我已经发现 dill 能够腌制类定义,并且肯定可以通过将 的定义复制MyClass到单独的脚本中并在那里腌制它来工作,如下所示:

import dill as pickle

class MyClass(object):
    ...

instance = MyClass(...)
with open(..., 'wb') as file:
   pickle.dump(instance, file)
Run Code Online (Sandbox Code Playgroud)

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

酸洗:

from MyModule.Submodule import MyClass
import dill as pickle

instance = MyClass(...)
with open(.., 'wb') as file:
    pickle.dump(instance, file)
Run Code Online (Sandbox Code Playgroud)

加载中:

import dill as pickle

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

>>> ModuleNotFoundError: No module named 'MyModule'
Run Code Online (Sandbox Code Playgroud)

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

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

相关问题: 为什么 dill 无论如何都会通过引用转储外部类

Mik*_*rns 2

我是dill作者。这是您上面提到的问题的重复。相关的 GitHub 功能请求为:https://github.com/uqfoundation/dill/issues/128

我认为更大的问题是您想要腌制另一个未安装的文件中定义的对象。我认为目前这是不可能的。

作为一种解决方法,我相信您可以dill.source通过提取类(或模块)的源代码并动态对其进行pickle,或者提取源代码并在__main__.