【问题标题】:multiprocessing and modules多处理和模块
【发布时间】:2015-12-10 12:41:18
【问题描述】:

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

main.py
multi/
    __init__.py (empty)
    base.py
    derived.py

ma​​in.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__()

派生的.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 方法中完全限定类名,但这只会给出相同的错误,即未定义 multi

是否有办法实现这一点,或者如果我想将multiprocessing 与继承一起使用,我必须重组以将所有类放在同一个包中?

【问题讨论】:

    标签: python python-2.7 python-multiprocessing


    【解决方案1】:

    这几乎肯定是由基于 eval 的可笑方法动态调用特定代码引起的。

    executeWrappedPoolMap(在base.py)中,您将一个类的str 名称转换为带有classType = eval(args[0])class 本身。但是eval是在executeWrappedPoolMap的范围内执行的,也就是在base.py里面,找不到derived(因为base.py里面不存在这个名字)。

    停止传递名称,传递class对象本身,传递classInstance.__class__而不是classInstance.__class__.__name__multiprocessing 会为你腌制它,你可以直接在另一端使用它,而不是使用 eval(这几乎总是错误的;这是最强烈的代码味道)。

    顺便说一句,回溯不是很有帮助的原因是异常在工作程序中引发,捕获,pickle-ed,然后发送回主进程并重新raise-ed。您看到的回溯来自那个 re-raise,而不是 NameError 实际发生的位置(在 eval 行中)。

    【讨论】:

    • 我最初遇到了实例酸洗问题,这就是为什么我将其更改为名称的 eval - 但显然这不是必需的。只需按照您的建议传递实例即可 - 谢谢。
    猜你喜欢
    • 1970-01-01
    • 2011-04-04
    • 2017-12-11
    • 2010-11-13
    • 1970-01-01
    • 2014-05-29
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多