Python 多处理与模块

Python 多处理与模块,python,python-2.7,python-multiprocessing,Python,Python 2.7,Python Multiprocessing,我试图使用多处理调用在不同模块中定义的派生类成员函数。似乎有几个问题涉及从同一个模块调用类方法,但没有一个问题来自不同的模块。例如,如果我有以下结构: 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(

我试图使用
多处理
调用在不同模块中定义的派生类成员函数。似乎有几个问题涉及从同一个模块调用类方法,但没有一个问题来自不同的模块。例如,如果我有以下结构:

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()
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__()
from base import base

class derived(base):
    def method(self,args):
        print "derived.method: " + args.__str__()
base.py

from multi.derived import derived
from multi.base import base

if __name__ == '__main__':
    base().multiFunction()
    derived().multiFunction()
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__()
from base import base

class derived(base):
    def method(self,args):
        print "derived.method: " + args.__str__()
派生的.py

from multi.derived import derived
from multi.base import base

if __name__ == '__main__':
    base().multiFunction()
    derived().multiFunction()
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__()
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
base.method:(0,)
基本方法:(1,)
基本方法:(2,)
回溯(最近一次呼叫最后一次):
文件“e:\temp\main.py”,第6行,在
派生()
文件“e:\temp\multi\base.py”,第15行,多功能
map(executeWrappedPoolMap,wrappoolmappargs(self,'method',range(3)))
映射中第251行的文件“C:\Program Files\Python27\lib\multiprocessing\pool.py”
返回self.map\u async(func,iterable,chunksize).get()
get中第567行的文件“C:\Program Files\Python27\lib\multiprocessing\pool.py”
提升自我价值
NameError:未定义名称“派生”
我曾尝试在
wrapPoolMethodArgs
方法中完全限定类名,但这只会产生相同的错误,即未定义
multi


如果我想将
多处理
与继承一起使用,是否有办法实现这一点,或者我必须重新构造,使所有类都位于同一个包中?

这几乎肯定是由基于
eval
的荒谬方法动态调用特定代码造成的

executeWrappedPoolMap
(在
base.py
)中,使用
classType=eval(args[0])
将类的
str
名称转换为
class
本身。但是
eval
是在
executeWrappedPoolMap
的范围内执行的,该范围位于
base.py
中,并且找不到
派生的
(因为该名称在
base.py
中不存在)

停止传递名称,并传递
class
对象本身,传递
classInstance.\uuuuu class\uuuuuu
而不是
classInstance.\uuuuu class\uuuuu.\uuuuu name\uuuu
<代码>多处理
将为您腌制它,您可以直接在另一端使用它,而不是使用
eval
(这几乎总是错误的;它的代码气味最强)


顺便说一下,回溯之所以没有什么特别的帮助,是因为异常是在工作人员中引发的,捕获的,
pickle
-ed,并被发送回主进程并重新-
rise
-ed。您看到的回溯来自于该re-
rise
,而不是实际发生的
nameferror
的地方(位于
eval
行中).

我最初在实例pickle方面遇到问题,这就是为什么我将其改为名称的eval-但显然这不是必需的。只需按照您的建议传递实例即可-谢谢。