实例方法不能在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实例方法不可能?
答案 0 :(得分: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 $ python test.py restore
加载泡菜
Foo.my_func
答案 1 :(得分: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