Python:使用`copyreg`为已经有reducer的类型定义reducer [英] Python: Using `copyreg` to define reducers for types that already have reducers
问题描述
我想使用 copyreg
模块来教Python如何清理函数。当我尝试这样做时, _Pickler
对象仍然会尝试使用 save_global
函数来调用函数。 (这对于未绑定的方法不起作用,这就是做这件事的动机。)
看起来像 _Pickler
在查找 copyreg.dispatch_table $ c $之前,首先尝试在它自己的
dispatch
中查找要腌的对象的类型C>。我不确定这是否是有意的。
有什么方法可以让我告诉Python使用我提供的reducer来调用函数?
以下hack似乎可以在Python 3.1中工作:
import copyreg
def functionpickler(f):
print('pickling',f .__ name__)
return f .__ name__
ft =类型(functionpickler)
copyreg.pickle(ft,functionpickler)
导入pickle
pickle.Pickler = pickle._Pickler $ b $ del pickle.Pickler.dispatch [ft]
$ bs = 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
;然而,这种酱腌菜本身也可能不太方便。
(Keep in mind I'm working in Python 3, so a solution needs to work in Python 3.)
I would like to use the copyreg
module to teach Python how to pickle functions. When I tried to do it, the _Pickler
object would still try to pickle functions using the save_global
function. (Which doesn't work for unbound methods, and that's the motivation for doing this.)
It seems like _Pickler
first tries to look in its own dispatch
for the type of the object that you want to pickle before looking in copyreg.dispatch_table
. I'm not sure if this is intentional.
Is there any way for me to tell Python to pickle functions with the reducer that I provide?
The following hack seems to work in 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)
Out of this, the two hackish lines are:
pickle.Pickler = pickle._Pickler
del pickle.Pickler.dispatch[ft]
You need to remove the dispatch
entry for functions' type because otherwise it preempts the copyreg registration; and I don't think you can do that on the C-coded Pickler so you need to set it to the Python-coded one.
It would be a bit less of a hack to subclass _Pickler
with a class of your own which makes its own dispatch
(copying the parent's and removing the entry for the function type), and then use your subclass specifically (and its dump method) rather than pickle.dump
; however it would also be a bit less convenient that this monkeypatching of pickle itself.
这篇关于Python:使用`copyreg`为已经有reducer的类型定义reducer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!