2012-04-09 16 views
1

我試圖使用多處理Pool類來將純函數映射到一些不可變對象上。然而,當我嘗試運行這個時,我發現終端中有很多錯誤(有時持續幾分鐘),而且經常,python'必須以一種不尋常的方式終止'。我在Windows(XP)上運行,使用python 3.2.2。從不可變對象讀取時使用multiprocessing.pool映射的錯誤

import multiprocessing 

def do_stuff(v): 
    return v.x + v.y 

class Vector: 
    __slots__ = ['x', 'y'] 

    def __setattr__(self, name, value): 
     raise AttributeError("Cannot assign values to object {0} of type {1}".format(self, type(self))) 

    def __init__(self, x, y = None): 
     """Initialize an immutable x, y Vector""" 
     object.__setattr__(self, 'x', x) 
     object.__setattr__(self, 'y', y) 

if __name__ == "__main__": 
    todo = [Vector(1, 2), Vector(3, 4), Vector(-1, 12), Vector(16, 32), Vector(16, 32)] 
    pool = multiprocessing.Pool(4) 
    results = list(pool.map(do_stuff, todo)) 
    print(results) 

預期輸出:

[3, 7, 11, 48, 48] 

錯誤的數量是非常大的,但它似乎歸結爲東西pool.map試圖在矢量設置屬性:

Process PoolWorker-1: 
Traceback (most recent call last): 
    File "c:\Python32\lib\multiprocessing\process.py", line 267, in _bootstrap 
Process PoolWorker-2: 
Traceback (most recent call last): 
    File "c:\Python32\lib\multiprocessing\process.py", line 267, in _bootstrap 
    self.run() 
    File "c:\Python32\lib\multiprocessing\process.py", line 116, in run 
    self._target(*self._args, **self._kwargs) 
    File "c:\Python32\lib\multiprocessing\pool.py", line 102, in worker 
    task = get() 
    File "c:\Python32\lib\multiprocessing\queues.py", line 378, in get 
    return recv() 
    File "d:\Documents and Settings\Userdir\Scripts\temp\test.py", line 11, in __s 
etattr__ 
    raise AttributeError("Cannot assign values to object {0} of type {1}".format 
(self, type(self))) 
AttributeError: Cannot assign values to object <__main__.Vector object at 0x00C2 
BBB0> of type <class '__main__.Vector'> 

我可以註釋掉從__slots__(奇怪?)開始的行,使用常規的map,或者我可以使Vector類變爲可變的(註釋掉__setattr__),並且其中任何一項都會使它工作正常。

爲什麼會試圖在我的對象上設置屬性,當我所做的只是從對象中讀取數據?

爲什麼從對象去除病因這__slots__才能正常工作?

編輯:

我使用__slots__爲節省內存/空間的方式,因爲通常在我的程序大量的載體。因此,我不能從一個元組得出矢量:__slots__ do not work for classes derived from ''variable-length'' built-in types such as long, str and tuple

+0

有沒有其他的方法來使一個類不可變,這對於這種情況有效? – Darthfett 2012-04-09 18:55:03

+0

'__slots__'可以節省大量矢量空間。 – Darthfett 2012-04-09 19:00:11

+0

啊,我以爲你假設'__slots__'的目的是讓Vector不可變。它確實解決了這個問題,如果它被髮布爲一個,我可以接受你的答案。 :) 非常感謝! – Darthfett 2012-04-09 19:18:01

回答

1

__slots__原因在unpickle問題multiprocessing,例如參見python multiprocessing pickle protocol

既然你不需要它的不變性(您__setattr__適合所有實際目的),我建議你刪除它。

如果您真的需要它來節省空間,然後實施__getstate____setstate__可以解決unpickling問題。

+1

我猜我遇到的問題是我不知道它是在酸洗物體。根據以下文檔:「在不知不覺中,可能會調用某些方法,例如__getattr __(),__getattribute __()或__setattr __()。」因此,爲了解決這個問題,我需要定義get/set狀態函數。 '__slots__'不適用於多處理。 – Darthfett 2012-04-09 19:39:26

相關問題