pickle在@staticmethod失败但在Python中成功使用staticmethod(func)

时间:2017-09-15 02:26:39

标签: python pickle static-methods

我试图在Multiprocessing.Pool模块中使用静态方法。我遇到了一些关于泡菜和静电方法的问题。

testcode:

from multiprocessing import Pool
import traceback
import copy_reg
import types

def _pickle_method(method):
    """
    Author: Steven Bethard (author of argparse)
    http://bytes.com/topic/python/answers/552476-why-cant-you-pickle-instancemethods
    """
    func_name = method.im_func.__name__
    obj = method.im_self
    cls = method.im_class
    cls_name = ''
    if func_name.startswith('__') and not func_name.endswith('__'):
        cls_name = cls.__name__.lstrip('_')
    if cls_name:
        func_name = '_' + cls_name + func_name
    return _unpickle_method, (func_name, obj, cls)


def _unpickle_method(func_name, obj, cls):
    """
    Author: Steven Bethard
    http://bytes.com/topic/python/answers/552476-why-cant-you-pickle-instancemethods
    """
    for cls in cls.mro():
        try:
            func = cls.__dict__[func_name]
        except KeyError:
            pass
        else:
            break
    return func.__get__(obj, cls)

copy_reg.pickle(types.MethodType, _pickle_method, _unpickle_method)

def test2():
    return "test2"

class Test(object):
    def __init__(self):
        pass

    def test1(self):
        return "test1"

    def test3():
        return "test3"
    @staticmethod
    def test4():
        return "test4"

    test2 = staticmethod(test2)
    test3 = staticmethod(test3)


def show_attributes(method):
    print "im_self=", method.im_self
    print "__self__=", method.__self__
    print "im_func=", method.im_func
    print "__func__=", method.__func__
    print "im_class=", method.im_class
    print "__doc__=", method.__doc__
    print "__module__=", method.__module__

if __name__ == "__main__":
    POOL_SIZE = 1


    ins = Test()
    pool1 = Pool(processes=1)
    res = pool1.apply_async(ins.test1)
    print(res.get())
    pool1.close()
    pool1.join()

    pool2 = Pool(processes=1)
    res = pool2.apply_async(Test.test2)
    print(res.get())
    pool2.close()
    pool2.join()

    try:
        pool3 = Pool(processes=1)
        res = pool3.apply_async(Test.test3)
        print(res.get())
        pool3.close()
        pool3.join()
    except:
        traceback.print_exc()

    pool4 = Pool(processes=1)
    res = pool4.apply_async(Test.test4)
    print(res.get())
    pool4.close()
    pool4.join()

输出:

test1
test2
Traceback (most recent call last):
  File "test.py", line 88, in <module>
    print(res.get())
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 567, in get
    raise self._value
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
Traceback (most recent call last):
  File "test.py", line 96, in <module>
    print(res.get())
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 567, in get
    raise self._value
cPickle.PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed

让我很困惑的是@staticmethod和staticmethod之间的行为完全不同。我想知道一些关于这方面的细节,以及如何正确地挑选我的@staticmethod方法。

任何人都知道问题可能是什么,或者只是轻松解决它?

THX !!!

0 个答案:

没有答案