Python:使用`copyreg`为已经有reducer的类型定义reducer [英] Python: Using `copyreg` to define reducers for types that already have reducers

查看:163
本文介绍了Python:使用`copyreg`为已经有reducer的类型定义reducer的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(请记住我在Python 3中工作,因此解决方案需要在Python 3中工作。)



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



看起来像 _Pickler 在查找 copyreg.dispatch_table 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆