I would like to serialize on machine A and deserialize on machine B a python lambda. There are a couple of obvious problems with that:
- the pickle module does not serialize or deserialize code. It only serializes the names of classes/methods/functions
- some of the answers I found with google suggest the use of the low-level marshal module to serialize the func_code attribute of the lambda but they fail to describe how one could reconstruct a function object from the deserialized code object
- marhshal(l.func_code) will not serialize the closure associated with the lambda which leads to the problem of detecting when a given lambda really needs a closure and warning the user that he is trying to serialize a lambda that uses a closure
Hence, my question(s):
- how would one reconstruct a function from the deserialized (demarshaled) code object ?
- how would one detect that a given lambda will not work properly without the associated closure ?
I'm not sure exactly what you want to do, but you could try dill. Dill can serialize and deserialize lambdas and I believe also works for lambdas inside closures. The pickle API is a subset of it's API. To use it, just "import dill as pickle" and go about your business pickling stuff.
Dill registers it's types into the
pickle
registry, so if you have some black box code that usespickle
and you can't really edit it, then just importing dill can magically make it work without monkeypatching the 3rd party code. Or, if you want the whole interpreter session sent over the wire as an "python image", dill can do that too.You can easily send the image across ssh to another computer, and start where you left off there as long as there's version compatibility of pickle and the usual caveats about python changing and things being installed. As shown, you can also extract the source of the lambda that was defined in the previous session.
Dill also has some good tools for helping you understand what is causing your pickling to fail when your code fails.
Surprisingly, checking whether a lambda will work without its associated closure is actually fairly easy. According to the data model documentation, you can just check the
func_closure
attribute:Then serializing + loading the lambda is fairly straight forward:
It's worth taking a look at the documentation for the
FunctionType
:Notice that you can also supply a closure… Which means you might even be able to serialize the old function's closure then load it at the other end :)