Python:无法pickle模块对象错误
我正在尝试腌制一个大班并得到
类型错误:无法腌制模块对象
TypeError:尽管浏览了网络,但 ,我无法确切地弄清楚这意味着什么。我不确定哪个模块对象
造成了麻烦。有办法找到罪魁祸首吗?堆栈跟踪似乎没有表明任何内容。
I'm trying to pickle a big class and getting
TypeError: can't pickle module objects
despite looking around the web, I can't exactly figure out what this means. and I'm not sure which module object
is causing the trouble. is there a way to find the culprit? the stack trace doesn't seem to indicate anything.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Python 无法pickle 模块对象才是真正的问题。有充分的理由吗?我不这么认为。模块对象不可选取会导致 Python 作为并行/异步语言的脆弱性。如果你想pickle模块对象,或者Python中的几乎任何东西,那么使用
dill
。在此处获取
dill
:https://github.com/uqfoundation/dillPython's inability to pickle module objects is the real problem. Is there a good reason? I don't think so. Having module objects unpicklable contributes to the frailty of python as a parallel / asynchronous language. If you want to pickle module objects, or almost anything in python, then use
dill
.Get
dill
here: https://github.com/uqfoundation/dill我可以通过这种方式重现错误消息:
Do you have a class attribute thatreferences a module?
I can reproduce the error message this way:
Do you have a class attribute that references a module?
递归查找 Pickle 失败
受
wump
评论的启发:Python:无法pickle模块对象错误
这是一些快速代码这帮助我递归地找到了罪魁祸首。
它检查有问题的对象,看看它是否酸洗失败。
然后迭代尝试对
__dict__
中的键进行 pickle,返回仅失败的 pickling 列表。代码片段
示例 程序
示例输出
根本原因 - Redis 无法 pickle _thread.lock
在我的例子中,创建保存为对象属性的
Redis
实例会破坏 pickle。当您创建
Redis
实例时,它还会创建一个Threads
的connection_pool
并且线程锁无法被 pickle。在进行 pickle 之前,我必须在
multiprocessing.Process
中创建并清理Redis
。测试
在我的例子中,我试图腌制的类必须能够腌制。因此,我添加了一个单元测试,该测试创建该类的实例并对其进行腌制。这样,如果有人修改了该类,使其无法被 pickle,从而破坏了它在多处理(和 pyspark)中使用的能力,我们将检测到该回归并立即知道。
Recursively Find Pickle Failure
Inspired by
wump
's comment:Python: can't pickle module objects error
Here is some quick code that helped me find the culprit recursively.
It checks the object in question to see if it fails pickling.
Then iterates trying to pickle the keys in
__dict__
returning the list of only failed picklings.Code Snippet
Example Program
Example Output
Root Cause - Redis can't pickle _thread.lock
In my case, creating an instance of
Redis
that I saved as an attribute of an object broke pickling.When you create an instance of
Redis
it also creates aconnection_pool
ofThreads
and the thread locks can not be pickled.I had to create and clean up
Redis
within themultiprocessing.Process
before it was pickled.Testing
In my case, the class that I was trying to pickle, must be able to pickle. So I added a unit test that creates an instance of the class and pickles it. That way if anyone modifies the class so it can't be pickled, therefore breaking it's ability to be used in multiprocessing (and pyspark), we will detect that regression and know straight away.
根据 文档 :
如您所见,模块不属于此列表。请注意,使用
deepcopy
时也是如此,而不仅仅是pickle
模块,如deepcopy
文档中所述:一种可能的解决方法是使用 @property 装饰器而不是属性。
例如,这应该有效:
According to the documentation:
As you can see, modules are not part of this list. Note, that this is also true when using
deepcopy
and not only for thepickle
module, as stated in the documentation ofdeepcopy
:A possible workaround is using the
@property
decorator instead of an attribute.For example, this should work:
@Flask 2.x 用户
与“TypeError:无法pickle模块对象”
如果您在尝试使用
@dataclass
装饰器显示模型时遇到此错误,请确保您使用lazy=
db.relationship()
中的“joined”@Flask 2.x users
with "TypeError: can't pickle module objects"
If you have this error when trying to display your model using
@dataclass
decorator, ensure you are usinglazy='joined'
in yourdb.relationship()