python - 在 Python 中 pickle 静态方法

标签 python static-methods pickle

我一直在尝试 pickle 一个包含对静态类方法的引用的对象。 Pickle 失败(例如在 module.MyClass.foo 上)说明它不能被 pickle,因为 module.foo 不存在。
我提出了以下解决方案,使用包装器对象在调用时定位函数,保存容器类和函数名称:

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 这样的对象? 我不想更改全局 pickle 进程(例如使用 copy_reg),但以下模式会很棒: 类 MyClass(对象): @picklable_staticmethod 定义 foo(): 打印“完成”。

我在这方面的尝试没有成功,特别是因为我无法从 foo 函数中提取所有者类。我什至愿意满足于显式规范(例如 @picklable_staticmethod(MyClass)),但我不知道有什么方法可以在它所在的位置引用 MyClass 类正在定义中。

任何想法都会很棒!

与纳丹

最佳答案

这似乎可行。

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

诀窍是在从类中获取静态方法时阻止该类。

备选方案:您可以使用元类化为所有静态方法提供 .__parentclass__ 属性。然后您可以子类化 Pickler 并为每个子类实例提供自己的 .dispatch 表,然后您可以修改该表而不影响全局调度表 (Pickler.dispatch). pickle 、取消 pickle 和调用方法可能会更快一些。

关于python - 在 Python 中 pickle 静态方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1914261/

相关文章:

python - 如何解决pickle编码问题?

python - pickle 错误: AttributeError: Can't get attribute on <module '__main__' (built-in)>

python - 具有周期性边界条件的数据的直方图

python - 如何在 Mac OSX 中从 2.7 升级到 python 3.5

python - 引发似乎来自调用者的异常

python - Ubuntu 和 Django,没有名为 'django' 的模块

c++ - 为什么 QDir::rmdir 不是静态的?

c++ - 编译错误 - 静态成员

c# - 适当使用静态方法

python - 多进程初始化程序和 pickle