Skip to content Skip to sidebar Skip to footer

Pickling A Staticmethod In Python

I've been trying to pickle an object which contains references to static class methods. Pickle fails (for example on module.MyClass.foo) stating it cannot be pickled, as module.foo

Solution 1:

This seems to work.

classPickleableStaticMethod(object):
    def__init__(self, fn, cls=None):
        self.cls = cls
        self.fn = fn
    def__call__(self, *args, **kwargs):
        return self.fn(*args, **kwargs)
    def__get__(self, obj, cls):
        return PickleableStaticMethod(self.fn, cls)
    def__getstate__(self):
        return (self.cls, self.fn.__name__)
    def__setstate__(self, state):
        self.cls, name = state
        self.fn = getattr(self.cls, name).fn

The trick is to snag the class when the static method is gotten from it.

Alternatives: You could use metaclassing to give all your static methods a .__parentclass__ attribute. Then you could subclass Pickler and give each subclass instance its own .dispatch table which you can then modify without affecting the global dispatch table (Pickler.dispatch). Pickling, unpickling, and calling the method might then be a little faster.

Solution 2:

EDIT: modified after Jason comment.

I think python is correct in not letting pickling a staticmethod object - as it is impossible to pickle instance or class methods! Such an object would make very little sense outside of its context:

Check this: Descriptor Tutorial

import pickle

def dosomething(a, b):
    print a, b

class MyClass(object):
    dosomething = staticmethod(dosomething) 

o = MyClass()

pickled = pickle.dumps(dosomething)

This works, and that's what should be done - define a function, pickle it, and use such function as a staticmethod in a certain class.

If you've got an use case for your need, please write it down and I'll be glad to discuss it.

Post a Comment for "Pickling A Staticmethod In Python"