pythonsavepygamepicklerenpy

Python - How can I make this un-pickleable object pickleable?


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.


Solution

  • 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.