5

实例方法不能在 Python 2 或 Python 3 中自动腌制。

我需要使用 Python 3 腌制实例方法,并将Steven Bethard的示例代码移植到 Python 3:

import copyreg
import types

def _pickle_method(method):
    func_name = method.__func__.__name__
    obj = method.__self__
    cls = method.__self__.__class__
    return _unpickle_method, (func_name, obj, cls)

def _unpickle_method(func_name, obj, cls):
    for cls in cls.mro():
        try:
            func = cls.__dict__[func_name]
        except KeyError:
            pass
        else:
            break
    return func.__get__(obj, cls)

copyreg.pickle(types.MethodType, _pickle_method, _unpickle_method)

这种方法对于酸洗实例方法是万无一失的吗?或者有些事情会发生可怕的错误?我已经用一些模拟课程对其进行了测试,一切似乎都有效。

如果什么都不会出错,为什么在 Python 3 中不能使用标准的 pickle 实例方法?

4

2 回答 2

0

我实际上无法在 python 3.5.0 上重现原始问题,请参见以下示例。可能值得检查最新版本,看看它是否可以开箱即用:-)

import pickle
import sys

class Foo:

    @staticmethod
    def my_func():
        return 'Foo.my_func'


class Bar:
    pass

if __name__ == '__main__':
    if len(sys.argv) > 1 and sys.argv[1] == 'restore':
        print('loading pickle')
        with open('test.pickle', 'rb') as fp:
            restored = pickle.load(fp)
            print(restored.baz())
    else:
        print('saving pickle')
        b = Bar()
        b.baz = Foo.my_func

        with open('test.pickle', 'w+b') as fp:
            p = pickle.dump(b, fp)

(测试)~/test$ python test.py

保存泡菜

(test)~/test$ python test.py restore

加载泡菜

Foo.my_func

于 2015-09-24T12:21:17.900 回答
0

如果要腌制类实例(和实例方法),只需使用dill...

>>> import dill
>>> 
>>> class Foo:
...   def bar(self, x):
...     return self.y + x
...   def zap(self, y):
...     self.y = y
...   y = 1
... 
>>> f = Foo()
>>> f.zap(4)
>>> f.monty = 'python'
>>> 
>>> _f = dill.dumps(f)
>>> del Foo
>>> del f
>>> f = dill.loads(_f)
>>> f.monty
'python'
>>> f.y
4
>>> 
>>> _b = dill.dumps(f.bar)
>>> del f
>>> bar = dill.loads(_b)
>>> bar(4)
8
>>> 

dill当你删除类对象时工作,如上所示......所以如果你在没有定义类的情况下启动一个新的 python 会话,或者如果你更改类定义,它也可以工作。 dill甚至在您没有类对象的实例或可用的类实例时也可以使用。如果想看怎么做,看dill源码:https ://github.com/uqfoundation/dill

另见相关:https ://stackoverflow.com/a/21345273/2379433

于 2015-09-24T14:15:06.133 回答