使用并行python与实例方法?

时间:2014-12-15 12:51:48

标签: python pickle parallel-python

鉴于代码here,我试着致电:

p = ProgressBar(maxval=len(img_paths))

sm = SaliencyMaskSlic()
operations = [('img_resize', img_resize), ('sal_mask', sm.transform)]
args_list = [{'h_size':258}, {'cropped':True}]

pre_pipeline = Pipeline(ops=operations, arg_list=args_list)
ch = ColorHist('RGB', [6,6,6], [2,2], center=True, pre_pipeline = pre_pipeline)

for count,img_path in enumerate(img_paths):
    s.submit(ch.transform, (img_path,))
    p.update(count)
p.finish()

它提出了:

---------------------------------------------------------------------------
PicklingError                             Traceback (most recent call last)
<ipython-input-44-b62cf2241437> in <module>()
      9 
     10 for count,img_path in enumerate(img_paths):
---> 11     s.submit(ch.transform, (img_path,))
     12     p.update(count)
     13 p.finish()

/usr/local/lib/python2.7/dist-packages/pp-1.6.4-py2.7.egg/pp.pyc in submit(self, func, args, depfuncs, modules, callback, callbackargs, group, globals)
    458 
    459         sfunc = self.__dumpsfunc((func, ) + depfuncs, modules)
--> 460         sargs = pickle.dumps(args, self.__pickle_proto)
    461 
    462         self.__queue_lock.acquire()

PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed

为了使用pp库,我应该如何在Python中处理这种情况。或者其他解决方案有哪些?

2 个答案:

答案 0 :(得分:1)

如果想要使用pp,但有更强的酸洗 - 那么请使用dilldill序列化程序可以腌制大部分python。我是dill作者,并且已将pp扩展为使用dill

pp需要通过从对象中提取源代码来进行序列化,就像标准模块inspectinspect.getsource所做的那样。使用dill.source.getsource,您可以进行更强大的代码检查和源检索。

Python 2.7.8 (default, Jul 13 2014, 02:29:54) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from dill import source
>>> def test_source(obj):
...     _obj = source._wrap(obj)
...     assert _obj(1.57) == obj(1.57)
...     src = source.getimportable(obj, alias='_f')
...     exec src in globals(), locals()
...     assert _f(1.57) == obj(1.57)
...     name = source.getname(obj)
...     assert name == obj.__name__ or src.split("=",1)[0].strip()
... 
>>> def test_ppmap(obj):
...     from pathos.pp import ParallelPythonPool
...     p = ParallelPythonPool(2)
...     x = [1,2,3]
...     assert map(obj, x) == p.map(obj, x)
... 
>>> from math import sin
>>> f = lambda x: x+1
>>> def g(x):
...   return x+2
... 
>>> for func in [g, f, abs, sin]:
...   test_source(func)
...   test_ppmap(func)
... 
>>> 

您需要获取pp附带的pathos版本,并且最好在pathos.pp扩展名的顶部使用pp图层

这也适用于类实例,等等 - pathos.pp还提供异步映射(见下文)以及迭代器映射(未显示)。

>>> class B:
...   def zap(self, x): 
...     return x**2 + self.y
...   y = 1
... 
>>> b = B()
>>> 
>>> res = p.amap(b.zap, range(5))
>>> res.get()
[1, 2, 5, 10, 17]

更新:我现在构建一个pp的独立分支,使用dill进行更好的序列化,称为ppft。无需安装pathos即可获得它。如果您不关心拥有Pool界面,请使用ppft,如果您需要Pool界面,请使用pathos.pp

在此处获取代码:https://github.com/uqfoundation

答案 1 :(得分:0)

错误消息告诉您尝试发送的对象是不可删除的。它不可用的原因是,它是classic class。在Python 3中,new-style是默认的,但在Python 2中你需要从object继承:

尝试将class ColorHist():替换为class ColorHist(object):,看看它是否适合您。