用Python腌制静态方法 [英] Pickling a staticmethod in Python

查看:114
本文介绍了用Python腌制静态方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试腌制一个包含对静态类方法的引用的对象. 泡菜失败(例如,在module.MyClass.foo上)指出无法腌制,因为module.foo不存在.
我提出了以下解决方案,使用包装对象在调用时定位函数,保存容器类和函数名:

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 does not exist.
I have come up with the following solution, using a wrapper object to locate the function upon invocation, saving the container class and function name:

class PicklableStaticMethod(object):
    """Picklable version of a static method.
    Typical usage:
        class MyClass:
            @staticmethod
            def doit():
                print "done"
        # This cannot be pickled:
        non_picklable = MyClass.doit
        # This can be pickled:
        picklable = PicklableStaticMethod(MyClass.doit, MyClass)
    """
    def __init__(self, func, parent_class):
        self.func_name = func.func_name
        self.parent_class = parent_class
    def __call__(self, *args, **kwargs):
        func = getattr(self.parent_class, self.func_name)
        return func(*args, **kwargs)

我想知道,是否有更好的-更标准的方法-腌制这样的物体? 我不想对全局pickle进程(例如,使用copy_reg)进行更改,但是以下模式将非常有用: 类MyClass(object): @picklable_static方法 def foo(): 打印完成".

I am wondering though, is there a better - more standard way - to pickle such an object? I do not want to make changes to the global pickle process (using copy_reg for example), but the following pattern would be great: class MyClass(object): @picklable_staticmethod def foo(): print "done."

我的尝试没有成功,特别是因为我无法从foo函数中提取所有者类.我什至愿意满足明确的规范(例如@picklable_staticmethod(MyClass)),但是我不知道在定义它的地方直接引用MyClass类的任何方法.

My attempts at this were unsuccessful, specifically because I could not extract the owner class from the foo function. I was even willing to settle for explicit specification (such as @picklable_staticmethod(MyClass)) but I don't know of any way to refer to the MyClass class right where it's being defined.

任何想法都很棒!

与那坦

推荐答案

这似乎可行.

class PickleableStaticMethod(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.

替代方法:您可以使用元类化为所有静态方法赋予.__parentclass__属性.然后,您可以为Pickler子类,并为每个子类实例提供自己的.dispatch表,然后可以对其进行修改而不会影响全局调度表(Pickler.dispatch).酸洗,解酸和调用该方法可能会更快一些.

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.

这篇关于用Python腌制静态方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆