[EMAIL PROTECTED] wrote: > Chris wrote: > > Why can pickle serialize references to functions, but not methods? > > > > Pickling a function serializes the function name, but pickling a > > staticmethod, classmethod, or instancemethod generates an error. In > > these cases, pickle knows the instance or class, and the method, so > > what's the problem? Pickle doesn't serialize code objects, so why can't > > it serialize the name as it does for functions? Is this one of those > > features that's feasible, but not useful, so no one's ever gotten > > around to implementing it? > > I have often wondered this myself. I'm convinced that it would in fact > be useful -- more than once I've written a program that has lots of > objects with function pointers, and where it was inconvenient that the > method pointers could not be pickled. One compromise that I have used > before is to write a class such as: > > class InstanceMethodSet(object): > def __init__(self,methods): > self.methods = set(methods) > def __getstate__(self): > return [(method.im_self, method.im_func.func_name) > for method in self.method] > def __setstate__(self,state): > self.methods = set(getattr(obj,name) for obj,name in state) > > Obviously, this particular example is crude and not terribly robust, > but it seems to do the job -- it effectively lets you pickle a set of > instance method pointers. I don't know of any reason why instance > methods (or class or static methods) couldn't be pickled directly, > unless perhaps there exists some kind of pathological corner case that > would create Badness? > > -Matt
Thanks, that's quite clever. Although I think you'd still have to explicitly specify im_self for staticmethods. I could imagine a similar callable proxy that simply removes the direct method reference from the equation: class MethodProxy(object): def __init__(self, obj, method): self.obj = obj if isinstance(method, basestring): self.methodName = method else: assert callable(method) self.methodName = method.func_name def __call__(self, *args, **kwargs): return getattr(self.obj, self.methodName)(*args, **kwargs) picklableMethod = MethodProxy(someObj, someObj.method) -- http://mail.python.org/mailman/listinfo/python-list