我試圖使用多處理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
有沒有其他的方法來使一個類不可變,這對於這種情況有效? – Darthfett 2012-04-09 18:55:03
'__slots__'可以節省大量矢量空間。 – Darthfett 2012-04-09 19:00:11
啊,我以爲你假設'__slots__'的目的是讓Vector不可變。它確實解決了這個問題,如果它被髮布爲一個,我可以接受你的答案。 :) 非常感謝! – Darthfett 2012-04-09 19:18:01