谁能告诉我为什么我的代码和函数序列化处理程序在下面不起作用?该copyreg
模块对我来说相当陌生,不清楚下面的代码是否正确编写。
>>> import pickle, copyreg, types, marshal
>>> def average(*args):
return sum(args) / len(args)
>>> average_dump = pickle.dumps(average)
>>> del average
>>> average = pickle.loads(average_dump)
Traceback (most recent call last):
File "<pyshell#31>", line 1, in <module>
average = pickle.loads(average_dump)
AttributeError: 'module' object has no attribute 'average'
>>> copyreg.pickle(types.CodeType,
lambda code: (marshal.loads, (marshal.dumps(code),)),
marshal.loads)
>>> up = lambda co, ns, de, cl: types.FunctionType(co, globals(), na, de, cl)
>>> copyreg.pickle(types.FunctionType,
lambda function: (up, (function.__code__,
function.__name__,
function.__defaults__,
function.__closure__)),
up)
>>> def average(*args):
return sum(args) / len(args)
>>> average_dump
b'\x80\x03c__main__\naverage\nq\x00.'
>>> pickle.dumps(average)
b'\x80\x03c__main__\naverage\nq\x00.'
>>> del average; average = pickle.loads(average_dump)
Traceback (most recent call last):
File "<pyshell#39>", line 1, in <module>
del average; average = pickle.loads(average_dump)
AttributeError: 'module' object has no attribute 'average'
我的期望是,如果注册的函数正常工作,那么代码和函数对象都会被序列化。如果按预期工作,解酸功能也是可能的。
编辑:按照此答案Pickler
中的建议进行子类化。似乎也没有帮助。示例中的函数仍按名称而不是模块中的处理程序进行序列化。copyreg
>>> import pickle, copyreg, types, marshal
>>> copyreg.pickle(types.CodeType,
lambda code: (marshal.loads, (marshal.dumps(code),)),
marshal.loads)
>>> up = lambda co, ns, de, cl: types.FunctionType(co, globals(), na, de, cl)
>>> copyreg.pickle(types.FunctionType,
lambda function: (up, (function.__code__,
function.__name__,
function.__defaults__,
function.__closure__)),
up)
>>> class MyPickler(pickle.Pickler):
def __init__(self, *args):
super().__init__(*args)
self.dispatch_table = copyreg.dispatch_table
>>> def average(*args):
return sum(args) / len(args)
>>> x = io.BytesIO(); y = MyPickler(x)
>>> y.dump(average)
>>> x.getvalue()
b'\x80\x03c__main__\naverage\nq\x00.'