Python:使用`copyreg`为已经有reducers的类型定义reducer

时间:2010-05-28 21:48:27

标签: python function pickle

(请记住我在Python 3中工作,所以解决方案需要在Python 3中运行。)

我想使用copyreg模块教Python如何pickle函数。当我尝试这样做时,_Pickler对象仍然会尝试使用save_global函数来挑选函数。 (这对于未绑定的方法不起作用,这就是这样做的动机。)

在查看_Pickler之前,似乎dispatch首先尝试在自己的copyreg.dispatch_table中查找要腌制的对象的类型。我不确定这是否是故意的。

有没有办法让我告诉Python使用我提供的reducer进行pickle功能?

1 个答案:

答案 0 :(得分:1)

以下hack似乎适用于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)

出于这个原因,两条hack行是:

pickle.Pickler = pickle._Pickler
del pickle.Pickler.dispatch[ft]

您需要删除函数类型的dispatch条目,否则它会抢占copyreg注册;我不认为你可以在C编码的Pickler上做到这一点,所以你需要将它设置为Python编码的。

使用您自己的类创建自己的_Pickler(复制父项并删除函数类型的条目),将dispatch子类化为少一点,然后特别使用您的子类(及其转储方法)而不是pickle.dump;然而,这种泡菜本身的表现也不太方便。