2013-02-10 19 views
0

我很惊讶地了解到,在互联网上找到关于并行python(PP)和处理类的小教程和指南。我遇到了一个问题,我想要启动几个同一类的实例,然后再检索一些变量(例如并行读取5个数据文件,然后再检索它们的数据)。以下是一段简单的代码来说明我的问题:使用并行python和类

import pp 

class TestClass: 
    def __init__(self, i): 
     self.i = i 

    def doSomething(self): 
     print "\nI'm being executed!, i = "+str(self.i) 
     self.j = 2*self.i 
     print "self.j is supposed to be "+str(self.j) 
     return self.i 

class parallelClass: 
    def __init__(self): 
     job_server = pp.Server() 
     job_list = [] 
     self.instances = [] # for storage of the class objects 
     for i in xrange(3): 
      TC = TestClass(i) # initiate a new instance of the TestClass 
      self.instances.append(TC) # store the instance 
      job_list.append(job_server.submit(TC.doSomething,(),())) # add some jobs to the job_list 
     results = [job() for job in job_list] # execute order 66... 

     print "\nIf all went well there's a nice bunch of objects in here:" 
     print self.instances 
     print "\nAccessing an object's i works ok, but accessing j does not" 
     print "i = "+str(self.instances[2].i) 
     print "j = "+str(self.instances[2].j) 

if __name__ == '__main__' : 
    parallelClass() # initiate the program 

我已添加评论以方便您。我在这里做错了什么?

+0

怎么回事?你的程序的预期输出是什么,你取而代之的是什么?顺便说一句:为什么当你真正想要像'main'这样的函数时,你使用了一个'__init__'类。我永远不会期望创建一个类的实例会阻止我的整个程序。 – Bakuriu 2013-02-10 19:21:37

+0

@Bakuriu我希望程序打印一个实例的'j'的值。我得到一个'AttributeError:TestClass实例没有属性'j''来代替。不要担心'__init__',这段代码只是我实际程序的简化表示。 – MPA 2013-02-10 19:37:16

+0

我认为问题在于代码是在不同的对象上执行的。并行python简单的pickles对象并将它们发送到子进程,因此您可以修改对象的本地状态,但不会影响原始实例。你可以检查这个打印'self'的'id'到'doSomething'的'id'和''instances''中的元素的'id'。 – Bakuriu 2013-02-10 19:40:36

回答

1

您应该使用callbacks

一个callbacks是你传递给submit调用的函数。该函数将作为参数调用(have a look at the API for more arcane usage)。

在你的情况

设置回调:

class TestClass: 
    def doSomething(self): 
     j = 2 * self.i 
     return j # It's REQUIRED that you return j here. 

    def set_j(self, j): 
     self.j = j 

回调添加到作业提交呼叫

class parallellClass: 
     def __init__(self): 
      #your code... 
      job_list.append(job_server.submit(TC.doSomething, callback=TC.set_j)) 

大功告成。

我对代码做了一些改进,以避免在doSomething调用中使用self.j,并且只使用本地j变量。

正如评论中所述,在pp中,您只能传达工作结果。这就是为什么你返回这个变量,它会传递给回调。