多处理和模块

时间:2015-12-10 12:41:18

标签: python python-2.7 python-multiprocessing

我试图使用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().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方法中完全限定类名,但这只是给出了同样的错误,说multi未定义。

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

1 个答案:

答案 0 :(得分:1)

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

executeWrappedPoolMapbase.py)中,您可以使用str将类的class名称转换为classType = eval(args[0])。但是evalexecuteWrappedPoolMap范围内执行,base.py位于derived,并且无法找到base.py(因为该名称不存在于classclassInstance.__class__)。

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

顺便说一句,回溯不是非常有用的原因是,在工作程序中引发异常,被捕获,raise - 并且被发送回主进程并重新{{1} } -ed。您看到的回溯来自重新NameError,而不是eval实际发生的位置(位于public void click_edit_childwindow2(String objectName) { //Store the current window handle String winHandleBefore = driver.getWindowHandle(); //Perform the click operation that opens new window try{ WebElement elemnt = driver.findElement(By.xpath("//*[@id='main']/div[1]/table/tbody/tr[2]/td[6]/button")); elemnt.click(); driver.findElement(By.xpath("//*[@id='main']/div[1]/table/tbody/tr[2]/td[6]/button")).click(); //Switch to new window opened for(String winHandle : driver.getWindowHandles()){ driver.switchTo().window(winHandle); } // Perform the actions on new window driver.findElement(By.xpath("//*[@id='myModal']/div/div/div[2]/form/div/div[10]/div/button[1]")).click(); //Close the new window, if that window no more required //driver.close(); //Switch back to original browser (first window) driver.switchTo().window(winHandleBefore); //continue with original browser (first window) }catch(Exception e){ driver.findElement((By.xpath("//*[@id='logoutForm']/ul/li[2]/a"))).click(); } } 行)。