免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 24995 | 回复: 6

python multiprocessing关于PicklingError的问题 [复制链接]

论坛徽章:
0
发表于 2013-11-13 15:12 |显示全部楼层
大家接触到python多进程的一个典型的例子如下,程序执行起来也没有任何问题。
import multiprocessing

def f(x):
    return x*x

def go():
    pool = multiprocessing.Pool(processes=4)            
    #result = pool.apply_async(self.f, [10])     
    #print result.get(timeout=1)           
    print pool.map(f, range(10))


if __name__== '__main__' :
    go()
可是,一旦加入了class,程序就显示错误。程序和结果如下:
程序:
import multiprocessing

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

    def f(self, x):
        return x*x

    def go(self):
        pool = multiprocessing.Pool(processes=4)            
        #result = pool.apply_async(self.f, [10])     
        #print result.get(timeout=1)           
        print pool.map(self.f, range(10))

结果:
PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed
请问有什么解决方法?
谢谢

论坛徽章:
0
发表于 2013-11-13 16:13 |显示全部楼层
回复 1# HengGeneral

你在类里定义f,含有两个哑员self和x,map时就会出错。改成如下形式就没有问题了。
  1. import multiprocessing

  2. def func(x):
  3.     return x*x

  4. class someClass(object):
  5.     def __init__(self,func):
  6.         self.f = func

  7.     def go(self):
  8.         pool = multiprocessing.Pool(processes=4)
  9.         #result = pool.apply_async(self.f, [10])
  10.         #print result.get(timeout=1)
  11.         print pool.map(self.f, range(10))

  12. a=someClass(func)
  13. a.go()
复制代码
结果:
  1. $python f.py
  2. [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
复制代码

论坛徽章:
0
发表于 2013-11-13 16:38 |显示全部楼层
回复 2# Hadron74


    能再解释一下么。。map时出错是指?

论坛徽章:
0
发表于 2013-11-13 16:47 |显示全部楼层
回复 3# laike9m

我不是太理解map的过程,但是它必须把self对象传递到各个进程中才行,由于map只需要一个参数,self多了出来。我看了《Python标准库》,这里介绍的是它上的做法。
至于为什么报pickle的错,我也不明白。
   

论坛徽章:
0
发表于 2013-11-13 23:03 |显示全部楼层
回复 4# Hadron74


    我在SO上看到了这个问题,想必LZ应该也看到了:
http://stackoverflow.com/questions/1816958/cant-pickle-type-instancemethod-when-using-pythons-multiprocessing-pool-ma
http://stackoverflow.com/questions/7016567/picklingerror-when-using-multiprocessing

我在Python3.3.2 下测试,结果发现并没有这个问题。见下图:
1.jpg

然后在2.7下测试,同样报错,信息和LZ相同。

所以基本可以推断Python 3通过某种途径把这个bug解决了,让bound method也pickleable

然后找到了这个http://bugs.python.org/issue9276

在最后一行看见
2.jpg

说明确实Python 3修复了这个问题。根据上面提到的,参考pep-3154,有这样一段内容:
3.jpg

大意就是说,因为PEP-3155实现了__qualname__ (qualified name)这个属性,所以Python的pickle已经能够序列化以前不能的东西,比如bound和unbound method。

唯一有点奇怪的是,PEP 3154对应的版本是Python3.4,但是在3.3.2里面已经有了,不知道为什么

  1. class A():
  2.       def f(self,n):
  3.             print(n)

  4. a = A()
  5. import pickle
  6. pickle.dump((A,a), open('a.p', 'wb'))
复制代码
大家可以试试执行上面那段简单的代码,应该可以(至少我可以)正确生成a.p文件

论坛徽章:
0
发表于 2013-11-14 11:48 |显示全部楼层
回复 5# laike9m
分析得很详细呀,谢谢!

   

论坛徽章:
0
发表于 2014-03-26 20:05 |显示全部楼层
看了下python3.4的更新日志,确实有PEP3154,总之往后应该确定的没问题了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP