python - 多处理和模块

标签 python python-2.7 python-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 未定义。

是否有某种方法可以实现此目的,或者如果我想将多处理与继承一起使用,我必须重新构造以将所有类放在同一个包中吗?

最佳答案

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

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

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

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

关于python - 多处理和模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34202173/

相关文章:

python - 如果另一列中的值重复,如何获取 pandas 数据框中的最小列值?

python - 这个网站的价格是如何呈现的?

python - 运行谷歌应用程序引擎时出错 : unrecognized arguments: admin_console_server

regex - 无法在 Python 2.7 re 中编译 8 位 unicode 正则表达式范围

python - 对大型数据框应用 API 调用时出现问题?

python multiprocessing,管理器启动进程生成循环

python pool apply_async 和 map_async 不会在完整队列上阻塞

python - 从列表文件中查找包含至少一个单词的所有短语并将它们保存到新文件中

python - 使用 python 中的 openpyxl 读取存储在共享点位置的 xlsx?

python - 如何跨重叠摄像机检测物体