Pickling Python 3 中的未绑定方法

发布于 2024-09-03 04:58:50 字数 799 浏览 7 评论 0原文

我想在 Python 3.x 中 pickle 一个未绑定的方法。我收到此错误:

>>> class A:
...     def m(self):
...         pass
>>> import pickle
>>> pickle.dumps(A.m)
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    pickle.dumps(A.m)
  File "C:\Python31\lib\pickle.py", line 1358, in dumps
    Pickler(f, protocol, fix_imports=fix_imports).dump(obj)
_pickle.PicklingError: Can't pickle <class 'function'>: attribute lookup builtins.function failed

有人有这方面的经验吗?


注意:在 Python 2.x 中,默认情况下也不可能 pickle 未绑定的方法;我设法以某种我不明白的奇怪方式做到了这一点:我用 MethodType 类的 copy_reg 模块编写了一个减速器,它涵盖了绑定和非绑定方法。但reducer只解决了绑定方法的情况,因为它依赖于my_method.im_self。神秘的是,它还使得 Python 2.x 能够 pickle 未绑定的方法。这在 Python 3.x 上不会发生。

I would like to pickle an unbound method in Python 3.x. I'm getting this error:

>>> class A:
...     def m(self):
...         pass
>>> import pickle
>>> pickle.dumps(A.m)
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    pickle.dumps(A.m)
  File "C:\Python31\lib\pickle.py", line 1358, in dumps
    Pickler(f, protocol, fix_imports=fix_imports).dump(obj)
_pickle.PicklingError: Can't pickle <class 'function'>: attribute lookup builtins.function failed

Does anyone have experience with this?


Note: In Python 2.x it's also impossible to pickle unbound methods by default; I managed to do it there in some weird way I don't understand: I wrote a reducer with the copy_reg module for the MethodType class, which covers both bound and unbound methods. But the reducer only solved the case of the bound method, because it depended on my_method.im_self. Mysteriously it has also caused Python 2.x to be able to pickle unbound methods. This does not happen on Python 3.x.

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

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

发布评论

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

评论(1

甜是你 2024-09-10 04:58:51

这不能直接完成,因为在 Python 3 中,未绑定方法类型消失了:它只是一个函数:

>>> print (type (A.m))
<class 'function'>

Python 函数没有绑定到类,因此不可能仅通过以下方式来判断 Am 属于哪个类查看表达式结果。

根据您的具体需要,腌制/取消腌制(类,方法名称)的元组可能就足够了:

>>> print (pickle.loads (pickle.dumps ((A, 'm'))))
... (<class '__main__.A'>, 'm')

您可以简单地使用 getattr() 从这里获取方法(函数):

>>> cls, method = pickle.loads (pickle.dumps ((A, 'm')))
>>> print (getattr (cls, method))
... <function m at 0xb78878ec>

This cannot be done directly because in Python 3 unbound method type is gone: it is just a function:

>>> print (type (A.m))
<class 'function'>

Python functions are not bound to a class, so it is impossible to tell what class A.m belongs to just by looking at the expression result.

Depending on what exactly you need, pickling/unpickling a tuple of (class, method-name) might be good enough:

>>> print (pickle.loads (pickle.dumps ((A, 'm'))))
... (<class '__main__.A'>, 'm')

You can get the method (function) from here simply by using getattr():

>>> cls, method = pickle.loads (pickle.dumps ((A, 'm')))
>>> print (getattr (cls, method))
... <function m at 0xb78878ec>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文