Re: Missing pickling support for generic methods
PJ Eby <pje-Wh6+Hckhi6HFNGf7iClzIwC/[email protected]> Fri, 1 Feb 2013 22:00:49 -0500
| Newsgroups | gmane.comp.python.peak |
|---|---|
| Message-ID | <CALeMXf7k0LrqBPiyBJZDJ2u=Hfbj+YaUn=EgRmXdq32exa+=uQ@mail.gmail.com> |
On Fri, Feb 1, 2013 at 6:32 PM, Herv=E9 Coatanhay <[email protected]> wrote: > Hi, > > As a note, the `lock` issue occurs with stackless python, which allows > instancemethod pickling. In standard cpython it is "TypeError: can't pick= le > instancemethod objects" obviously. Try defining the method *outside* the class, then copying it inside, e.g.: @abstract def run(self, arg): pass class Test(object): run =3D run ... This should cause the pickler to see the generic function as a global function object rather than a standalone function. Essentially, the problem is that the function shouldn't be being pickled as a standalone object with state, it should be pickled as a thing imported from a particular module, so that when the pickle is loaded it just imports the function rather than *recreating* the function. If you're doing this a lot, you might be better off with a custom reducer for methods, something like: class MethodWrapper(object): def __init__(self, inst, name): self.reduction =3D (getattr, (inst, name)) def __reduce__(self): return self.reduction Pickling a 'MethodWrapper(inst, methodname)' will create a pickle that is loaded by fetching the named attribute from the (pickled) instance. (Better still, write a version of this that you can register in the copy_reg.dispatch_table as a custom handler for instance methods within your program.) In general, the workaround details are going to be highly specific to the pickle implementation used; pickle and cPickle do things differently, and if Stackless pickles methods, I imagine there are even more differences.