【问题标题】:Pickling an unbound method in Python 3在 Python 3 中腌制一个未绑定的方法
【发布时间】:2011-02-25 05:24:07
【问题描述】:

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

>>> 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 中,默认情况下也无法腌制未绑定的方法;我设法以某种我不理解的奇怪方式在那里做到了:我为 MethodType 类编写了一个带有copy_reg 模块的reducer,它涵盖了绑定和未绑定的方法。但是reducer只解决了绑定方法的情况,因为它依赖于my_method.im_self。不可思议的是,它还导致 Python 2.x 能够腌制未绑定的方法。这在 Python 3.x 上不会发生。

【问题讨论】:

    标签: python methods python-3.x pickle


    【解决方案1】:

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

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

    Python函数没有绑定到一个类,所以仅仅看表达式结果是无法判断A.m属于哪个类的。

    根据您的具体需要,腌制/取消腌制 (class, method-name) 的元组可能就足够了:

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

    【讨论】:

    • 你是说在 Python 3 上,给定一个未绑定的方法,没有办法知道该方法是在哪里定义的?
    • 是的。尝试声明两个类并将一种方法从一个分配给另一个(B.m = A.m)。那么B.mA.m 将相等(实际上,相同),因此无法判断您是在B 还是在A 中查找该方法。
    猜你喜欢
    • 2010-12-27
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 2017-08-14
    • 1970-01-01
    相关资源
    最近更新 更多