用Python腌制静态方法 [英] Pickling a staticmethod in 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屋!