2013-02-10 20 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中,您只能傳達工作結果。這就是爲什麼你返回這個變量,它會傳遞給回調。