多处理和模块
multiprocessing and modules
我正在尝试使用 multiprocessing
调用在不同模块中定义的派生 class 成员函数。似乎有几个问题涉及从同一模块调用 class 方法,但从不同模块调用 none 方法。例如,如果我有以下结构:
main.py
multi/
__init__.py (empty)
base.py
derived.py
main.py
from multi.derived import derived
from multi.base import base
if __name__ == '__main__':
base().multiFunction()
derived().multiFunction()
base.py
import multiprocessing;
# The following two functions wrap calling a class method
def wrapPoolMapArgs(classInstance, functionName, argumentLists):
className = classInstance.__class__.__name__
return zip([className] * len(argumentLists), [functionName] * len(argumentLists), [classInstance] * len(argumentLists), argumentLists)
def executeWrappedPoolMap(args, **kwargs):
classType = eval(args[0])
funcType = getattr(classType, args[1])
funcType(args[2], args[3:], **kwargs)
class base:
def multiFunction(self):
mppool = multiprocessing.Pool()
mppool.map(executeWrappedPoolMap, wrapPoolMapArgs(self, 'method', range(3)))
def method(self,args):
print "base.method: " + args.__str__()
derived.py
from base import base
class derived(base):
def method(self,args):
print "derived.method: " + args.__str__()
输出
base.method: (0,)
base.method: (1,)
base.method: (2,)
Traceback (most recent call last):
File "e:\temp\main.py", line 6, in <module>
derived().multiFunction()
File "e:\temp\multi\base.py", line 15, in multiFunction
mppool.map(executeWrappedPoolMap, wrapPoolMapArgs(self, 'method', range(3)))
File "C:\Program Files\Python27\lib\multiprocessing\pool.py", line 251, in map
return self.map_async(func, iterable, chunksize).get()
File "C:\Program Files\Python27\lib\multiprocessing\pool.py", line 567, in get
raise self._value
NameError: name 'derived' is not defined
我已经尝试在 wrapPoolMethodArgs
方法中完全限定 class 名称,但这只会给出相同的错误,说 multi
未定义。
有什么方法可以实现这一点,或者如果我想使用 multiprocessing
继承,我必须重组以将所有 class 放在同一个包中吗?
这几乎可以肯定是由基于 eval
的动态调用特定代码的荒谬方法引起的。
在 executeWrappedPoolMap
中(在 base.py
中),您将 class 的 str
名称转换为 class
本身 classType = eval(args[0])
.但是eval
是在executeWrappedPoolMap
的范围内执行的,在base.py
,找不到derived
(因为名字在[=12=中不存在) ]).
停止传递名称,传递 class
对象本身,传递 classInstance.__class__
而不是 classInstance.__class__.__name__
; multiprocessing
会为你 pickle,你可以直接在另一端使用它,而不是使用 eval
(这几乎总是错误的;它是最强烈的代码味道)。
顺便说一句,回溯不是很有用的原因是异常在 worker 中引发、捕获、pickle
-ed,然后发送回主进程并重新 raise
-编辑。您看到的回溯来自 re-raise
,而不是 NameError
实际发生的地方(在 eval
行)。
我正在尝试使用 multiprocessing
调用在不同模块中定义的派生 class 成员函数。似乎有几个问题涉及从同一模块调用 class 方法,但从不同模块调用 none 方法。例如,如果我有以下结构:
main.py
multi/
__init__.py (empty)
base.py
derived.py
main.py
from multi.derived import derived
from multi.base import base
if __name__ == '__main__':
base().multiFunction()
derived().multiFunction()
base.py
import multiprocessing;
# The following two functions wrap calling a class method
def wrapPoolMapArgs(classInstance, functionName, argumentLists):
className = classInstance.__class__.__name__
return zip([className] * len(argumentLists), [functionName] * len(argumentLists), [classInstance] * len(argumentLists), argumentLists)
def executeWrappedPoolMap(args, **kwargs):
classType = eval(args[0])
funcType = getattr(classType, args[1])
funcType(args[2], args[3:], **kwargs)
class base:
def multiFunction(self):
mppool = multiprocessing.Pool()
mppool.map(executeWrappedPoolMap, wrapPoolMapArgs(self, 'method', range(3)))
def method(self,args):
print "base.method: " + args.__str__()
derived.py
from base import base
class derived(base):
def method(self,args):
print "derived.method: " + args.__str__()
输出
base.method: (0,)
base.method: (1,)
base.method: (2,)
Traceback (most recent call last):
File "e:\temp\main.py", line 6, in <module>
derived().multiFunction()
File "e:\temp\multi\base.py", line 15, in multiFunction
mppool.map(executeWrappedPoolMap, wrapPoolMapArgs(self, 'method', range(3)))
File "C:\Program Files\Python27\lib\multiprocessing\pool.py", line 251, in map
return self.map_async(func, iterable, chunksize).get()
File "C:\Program Files\Python27\lib\multiprocessing\pool.py", line 567, in get
raise self._value
NameError: name 'derived' is not defined
我已经尝试在 wrapPoolMethodArgs
方法中完全限定 class 名称,但这只会给出相同的错误,说 multi
未定义。
有什么方法可以实现这一点,或者如果我想使用 multiprocessing
继承,我必须重组以将所有 class 放在同一个包中吗?
这几乎可以肯定是由基于 eval
的动态调用特定代码的荒谬方法引起的。
在 executeWrappedPoolMap
中(在 base.py
中),您将 class 的 str
名称转换为 class
本身 classType = eval(args[0])
.但是eval
是在executeWrappedPoolMap
的范围内执行的,在base.py
,找不到derived
(因为名字在[=12=中不存在) ]).
停止传递名称,传递 class
对象本身,传递 classInstance.__class__
而不是 classInstance.__class__.__name__
; multiprocessing
会为你 pickle,你可以直接在另一端使用它,而不是使用 eval
(这几乎总是错误的;它是最强烈的代码味道)。
顺便说一句,回溯不是很有用的原因是异常在 worker 中引发、捕获、pickle
-ed,然后发送回主进程并重新 raise
-编辑。您看到的回溯来自 re-raise
,而不是 NameError
实际发生的地方(在 eval
行)。