Python - 如何使这个不可腌制的对象可腌制?
问题描述
所以,我有一个对象,里面有很多不可腌制的东西(pygame 事件、orderedDicts、时钟等),我需要将它保存到磁盘.
问题是,如果我可以让这个东西存储一个有进度的字符串(我只需要一个整数),那么我可以将它传递给对象的 init,它会重建所有这些东西.不幸的是,我使用的框架 (Renpy) 会腌制对象并尝试加载它,尽管我可以将其保存为单个整数,但我无法更改.p>
所以,我要问的是,我怎样才能覆盖方法,以便当 pickle 尝试保存对象时,它只保存进度值,并且每当它尝试加载对象时,它都会从进度值?
我已经看到一些关于 __repr__ 方法的讨论,但我不确定在我的情况下如何使用它.
解决方案你要找的钩子是 __reduce__
.它应该返回一个 (callable, args)
元组;callable
和 args
将被序列化,并且在反序列化时,将通过 callable(*args)
重新创建对象.如果您的类的构造函数采用 int,您可以将 __reduce__
实现为
类 ComplicatedThing:def __reduce__(self):返回 (ComplicatedThing, (self.progress_int,))
您可以在元组中添加一些可选的额外内容,当您的对象图具有循环依赖关系时最有用,但您在这里不需要它们.
So, I have an object that has quite a bit of non-pickleable things in it (pygame events, orderedDicts, clock, etc.) and I need to save it to disk.
Thing is, if I can just get this thing to store a string that has the progress (a single integer is all I need), then I can pass it to the object's init and it will rebuild all of those things. Unfortunately, a framework I am using (Renpy) will pickle the object and attempt to load it, despite the fact that I could save it as a single integer, and I can't change that.
So, what I'm asking is, how can I override methods so that whenever pickle tries to save the object, it saves only the progress value, and whenever it tries to load the object, it creates a new instance from the progress value?
I've seen a bit talking bout the __repr__ method, but I am unsure how I would use this in my situation.
解决方案The hook you're looking for is __reduce__
. It should return a (callable, args)
tuple; the callable
and args
will be serialized, and on deserialization, the object will be recreated through callable(*args)
. If your class's constructor takes an int, you can implement __reduce__
as
class ComplicatedThing:
def __reduce__(self):
return (ComplicatedThing, (self.progress_int,))
There are a few optional extra things you can put into the tuple, mostly useful for when your object graph has cyclic dependencies, but you shouldn't need them here.
相关文章