Python:使用“copyreg”为已有减速器的类型定义减速器

发布于 2024-09-03 12:51:40 字数 396 浏览 5 评论 0原文

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

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

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

我有什么方法可以告诉Python使用我提供的reducer来pickle函数吗?

(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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

以往的大感动 2024-09-10 12:51:40

以下 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。

使用您自己的类对 _Pickler 进行子类化,从而生成自己的 dispatch (复制父级并删除函数类型的条目),这样就不会那么麻烦了。 ,然后专门使用您的子类(及其转储方法)而不是 pickle.dump;然而,与泡菜本身的猴子修补相比,它也不太方便。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文