Python 在未安装cloudpickle的情况下解除对cloudpickle的粘贴

Python 在未安装cloudpickle的情况下解除对cloudpickle的粘贴,python,pickle,Python,Pickle,Python标准库中的默认pickle模块不允许使用闭包、lambda或\uuuuuu main\uuuuuu中的函数进行序列化(请参阅) 我需要使用一些自定义函数来pickle一个对象,这些自定义函数在取消pickle的地方是不可导入的。还有一些其他的Python对象序列化程序,包括dill和cloudpickle,能够完成这项工作 cloudpickle似乎在说,即使使用cloudpickle进行pickle,也可以使用标准的pickle模块取消pickle。这非常有吸引力,因为我甚至不能在

Python标准库中的默认
pickle
模块不允许使用闭包、lambda或
\uuuuuu main\uuuuuu
中的函数进行序列化(请参阅)

我需要使用一些自定义函数来pickle一个对象,这些自定义函数在取消pickle的地方是不可导入的。还有一些其他的Python对象序列化程序,包括
dill
cloudpickle
,能够完成这项工作

cloudpickle
似乎在说,即使使用
cloudpickle
进行pickle,也可以使用标准的
pickle
模块取消pickle。这非常有吸引力,因为我甚至不能在需要解压的环境中安装软件包

实际上,文档中的示例基本上实现了以下功能:

泡菜: 解钩: 但是,在未安装
cloudpickle
的环境中运行第二个块,即使从未导入,也会产生错误:

"ImportError: No module named cloudpickle.cloudpickle"
最容易复制的示例可能是为Python2安装
cloudpickle
,运行第一个块,然后尝试使用Python3将第二个块加载到pickle文件中(其中未安装
cloudpickle


这是怎么回事?如果标准的
pickle
加载甚至没有被调用,为什么需要安装
cloudpickle
来运行它?

理论上,
cloudpickle
不需要安装到
load
一个pickle对象。从理论上讲,
cloudpickle
所能做的就是包含所有必要的函数,以便在该对象中取消勾选对象。然而,这是理论上的

在方法注册表中(例如,使用
copyreg
),序列化程序需要注册方法,使序列化程序能够创建所需类型的新对象,并将保存状态嵌入其中。为了使序列化程序不需要在加载时安装,序列化程序需要在pickle对象本身中包含所有必需的反序列化方法(这是可能的,因为pickle是递归的)


cloudpickle
假设安装了
cloudpickle
,因此(为了使生成的pickle对象更小),不包括所有必需的方法。这与
numpy
不同,作为反例,
方法转储到
numpy.array
上,但在pickle中包含
recostruct
方法(您可以将其视为
numpy.core.multiarray\n\u recostruct
出现在
数组的任何pickle中).

您知道
cloudpickle
是否可以进行递归,从而不需要安装它来取消pickle吗?或者答案是“它需要安装”。我是
dill
的作者,所以我只能在理论上为
cloudpickle
说话……然而,如果你想用forking
cloudpickle
来做这件事,我认为答案是“不”,至少不容易——你需要安装
cloudpickle
。解决方法是,您需要使用
copyreg
cloudpickle
使用的每一个方法注册到
pickle
中,然后还将生成的方法表(它是一个dict)保存为第一次打开的pickle(以便可以从
globals
引用)在目标对象取消勾选之前。与此类似:
>>> import pickle
>>> new_squared = pickle.load(open('pickled_file', 'rb'))
>>> new_squared(2)
"ImportError: No module named cloudpickle.cloudpickle"