Python:使用`copyreg`为已有 reducers 的类型定义 reducers
(请注意,我是在使用Python 3,所以解决方案需要适用于Python 3。)
我想用copyreg
模块来教Python如何处理函数的序列化,也就是把函数保存成可以存储的格式。当我尝试这样做时,_Pickler
对象仍然会用save_global
函数来处理函数的序列化。(这个方法对未绑定的方法不起作用,这也是我想这么做的原因。)
看起来_Pickler
会先在自己的dispatch
中查找你想序列化的对象类型,然后再去copyreg.dispatch_table
中查找。我不确定这是故意的还是怎样。
有没有办法让我告诉Python用我提供的处理器来序列化函数呢?
1 个回答
1
下面这个小技巧在Python 3.1中似乎有效……:
import copyreg
def functionpickler(f):
print('pickling', f.__name__)
return f.__name__
ft = type(functionpickler)
copyreg.pickle(ft, functionpickler)
import pickle
pickle.Pickler = pickle._Pickler
del pickle.Pickler.dispatch[ft]
s = pickle.dumps(functionpickler)
print('Result is', s)
从中可以看到,这两行小技巧是:
pickle.Pickler = pickle._Pickler
del pickle.Pickler.dispatch[ft]
你需要去掉函数类型的dispatch
条目,因为如果不去掉,它会干扰到copyreg的注册。而且我觉得你不能在用C语言写的Pickler上做到这一点,所以你需要使用用Python写的那个。
如果你自己创建一个类来继承_Pickler
,并自己定义一个dispatch
(复制父类的并去掉函数类型的条目),这样做会稍微少一点黑科技的感觉。然后你可以专门使用你的子类(和它的dump方法),而不是直接用pickle.dump
;不过这样做会比直接修改pickle本身稍微麻烦一点。