如何在大型对象上查找 Python Pickle 中的错误源
我已经接管了某人的一个相当大的项目的代码。我正在尝试保存程序状态,并且有一个巨大的对象存储了几乎所有其他对象。我正在尝试腌制这个对象,但出现以下错误:
pickle.PicklingError:无法pickle:找不到内置.module
从我在谷歌上找到的内容来看,这是因为我在 python init 之外导入了一些东西,或者是一个类属性正在引用一个模块。所以,我有两个问题:
任何人都可以确认这就是出现此错误的原因吗?我是否在代码中寻找正确的内容?
有没有办法找到哪行代码/对象成员导致了pickle中的困难?回溯仅给出 pickle 中发生错误的行,而不是被 pickle 的对象的行。
I've taken over somebody's code for a fairly large project. I'm trying to save program state, and there's one massive object which stores pretty much all the other objects. I'm trying to pickle this object, but I get this error:
pickle.PicklingError: Can't pickle : it's not found as builtin.module
From what I can find on google, this is because somewhere I'm importing something outside of python init, or that a class attribute is referencing a module. So, I've got a two questions:
Can anybody confirm that that's why this error is being given? Am I looking for the right things in my code?
Is there a way to find what line of code/object member is causing the difficulties in pickle? The traceback only gives the line in pickle where the error occurs, not the line of the object being pickled.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
2)您可以将 pickle.Pickler 子类化并对其进行猴子修补以显示其腌制内容的日志。这应该可以更容易地追踪问题所在。
这仅适用于 pickle.Pickler 的 Python 实现。在Python 3.x中,pickle模块默认使用C实现,Pickler的纯Python版本称为_Pickler。
2) You can subclass pickle.Pickler and monkey-patch it to show a log of what it's pickling. This should make it easier to trace where the problem is.
This will only work with the Python implementation of pickle.Pickler. In Python 3.x, the pickle module uses the C implementation by default, the pure-Python version of Pickler is called _Pickler.
dill
中存在类似的东西。让我们看一下对象列表,看看我们能做什么:好吧,
dill
无法对列表进行 pickle。那么问题出在哪里呢?好的,列表中的第一项无法腌制。剩下的呢?
嗯。其他物体腌制得很好。那么,让我们替换第一个对象。
现在我们的对象泡菜。好吧,我们可以利用在 linux/unix/mac 上进行 pickle 时发生的一些内置对象共享……那么更强的检查怎么样,比如跨子进程的实际 pickle(就像在 Windows 上发生的那样)?
不,列表仍然有效......所以这是一个可以成功发送到另一个进程的对象。
现在,关于您的错误,每个人似乎都忽略了......
ModuleType
对象不可pickle,这导致了您的错误。然而,如果我们导入
dill
,它就会神奇地起作用。Something like this exists in
dill
. Let's look at a list of objects, and see what we can do:Ok,
dill
fails to pickle the list. So what's the problem?Ok, the first item in the list fails to pickle. What about the rest?
Hm. The other objects pickle just fine. So, let's replace the first object.
Now our object pickles. Well, we could be taking advantage of some built-in object sharing that happens for pickling on linux/unix/mac… so what about a stronger check, like actually pickling across a sub-process (like happens on windows)?
Nope, the list still works… so this is an object that could be sent to another process successfully.
Now, with regard to your error, which everyone seemed to ignore…
The
ModuleType
object is not pickleable, and that's causing your error.However, if we import
dill
, it magically works.作为查找导致问题的对象属性/成员的快速而肮脏的方法,您可以尝试:
As a quick-and-dirty way to find what attribute/member of the object is causing the problem, you could try:
1)与您发现的略有不同。这是由引用模块类型(不是直接模块)的某些变量(类属性、列表或字典项,它可以是任何东西)引起的问题。此代码应该重现该问题:
1) There's a slight difference from what you've found. This is a problem caused by some variable (class attribute, list or dict item, it could be anything) that is referencing the module type (not a module directly). This code should reproduce the issue: