Python 将动态加载的函数用作multiprocessing.Pool的目标

Python 将动态加载的函数用作multiprocessing.Pool的目标,python,multiprocessing,pyside,Python,Multiprocessing,Pyside,我正在开发一个GUI,它需要在后台执行一些繁重的计算,然后在计算完成后更新GUI。多处理模块似乎是一个很好的解决方案,因为我可以使用*apply\u async*方法来指定目标函数和回调函数。回调函数用于使用结果更新GUI。但是,在尝试将多处理与动态加载的模块结合起来时,我遇到了困难,如下面的代码所示。错误消息为ImportError:没有名为calc的模块 这个错误是因为多处理不能处理动态加载的模块吗?如果没有,有没有更好的方法 from PySide.QtCore import * from

我正在开发一个GUI,它需要在后台执行一些繁重的计算,然后在计算完成后更新GUI。多处理模块似乎是一个很好的解决方案,因为我可以使用*apply\u async*方法来指定目标函数和回调函数。回调函数用于使用结果更新GUI。但是,在尝试将多处理与动态加载的模块结合起来时,我遇到了困难,如下面的代码所示。错误消息为ImportError:没有名为calc的模块

这个错误是因为多处理不能处理动态加载的模块吗?如果没有,有没有更好的方法

from PySide.QtCore import *
from PySide.QtGui import *
import multiprocessing
import time
import sys
import os
import logging
import imp

PluginFolder = "plugins"
plugins = {}

def f(x):
    y = x*x
    time.sleep(2) #Simulate processing time.
    return y


def load_plugin(name):
    '''Load the python module 'name'
    '''
    location = os.path.join('.', PluginFolder)
    info = imp.find_module(name, [location])
    plugin = {"name": name, "info": info}
    plugins[name] = imp.load_module(name, *plugin["info"])


class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.pool = multiprocessing.Pool() 
        load_plugin('calc') #load ./plugins/calc.py

        button1 = QPushButton('Calculate', self)
        button1.clicked.connect(self.calculate)
        button2 = QPushButton('Test', self)
        button2.clicked.connect(self.run_test)
        self.text = QTextEdit()

        vbox1 = QVBoxLayout()
        vbox1.addWidget(button1)
        vbox1.addWidget(button2)
        vbox1.addWidget(self.text)
        myframe = QFrame()
        myframe.setLayout(vbox1)

        self.setCentralWidget(myframe)
        self.show()
        self.raise_()



    def calculate(self):
        #self.pool.apply_async(f, [10], callback=self.update_gui) #This works

        #result = plugins['calc'].f(10) #this works
        #self.update_gui(result)

        self.pool.apply_async(plugins['calc'].f, [10], callback=self.update_gui) #This doesn't


    def update_gui(self, result):
        self.text.append('Calculation complete. Result = %d\n' % result)


    def run_test(self):
        self.text.append('Testing\n')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    gui = MainWindow()
    app.exec_()

在./plugins/calc.py中,函数f的定义如上述代码所示。

这不起作用,因为您将
calc
模块作为顶级模块加载。由于您的
sys.path
或当前目录中不存在模块
calc
,导入语句无法找到该模块。用以下语句替换import语句将完成以下操作:

plugins[name] = imp.load_module('{}.{}'.format(PluginFolder, name), 
                     *plugin["info"])
对于可导入的
plugin.calc
plugins
必须是一个python模块,即包含一个
\uuuu init\uuuu.py
文件

插件文件中的任何
import
语句,例如
plugins/calc.py
,都将导致警告

RuntimeWarning: Parent module 'plugins' not found while handling absolute import import <module>
RuntimeWarning:处理绝对导入时未找到父模块“插件”

原因是导入过程会查看父模块是否包含
,而在
calc.py
中,找不到父模块
插件。您可以使用主代码中的
import plugins
语句来明确指定
插件
模块位置,从而消除错误。

这不起作用,因为您将
calc
模块作为顶级模块加载。由于您的
sys.path
或当前目录中不存在模块
calc
,导入语句无法找到该模块。用以下语句替换import语句将完成以下操作:

plugins[name] = imp.load_module('{}.{}'.format(PluginFolder, name), 
                     *plugin["info"])
对于可导入的
plugin.calc
plugins
必须是一个python模块,即包含一个
\uuuu init\uuuu.py
文件

插件文件中的任何
import
语句,例如
plugins/calc.py
,都将导致警告

RuntimeWarning: Parent module 'plugins' not found while handling absolute import import <module>
RuntimeWarning:处理绝对导入时未找到父模块“插件”

原因是导入过程会查看父模块是否包含
,而在
calc.py
中,找不到父模块
插件。您可以通过主代码中的
import plugins
语句来明确指定
plugins
模块位置,从而消除错误。

这似乎不起作用。出现警告:。\plugins\calc.py:6:RuntimeWarning:在处理绝对导入时未找到父模块“plugins”,并出现错误:PicklingError:无法pickle:属性查找内置函数failed@mr_js请澄清您的代码结构,您的
插件
文件夹中是否有
\uuuu init\uuuuuuuy.py
;你的主代码在哪里?谢谢。解决方案是将
\uuuu init\uuuuuuuuuupy
添加到plugins文件夹,现在您的答案是将名称更改为
plugins.calc
有效。但是警告仍然存在:。\plugins\calc.py:6:RuntimeWarning:处理绝对导入时未找到父模块“plugins”time@alco谢谢你的解释。现在起作用了。这似乎不起作用。出现警告:。\plugins\calc.py:6:RuntimeWarning:在处理绝对导入时未找到父模块“plugins”,并出现错误:PicklingError:无法pickle:属性查找内置函数failed@mr_js请澄清您的代码结构,您的
插件
文件夹中是否有
\uuuu init\uuuuuuuy.py
;你的主代码在哪里?谢谢。解决方案是将
\uuuu init\uuuuuuuuuupy
添加到plugins文件夹,现在您的答案是将名称更改为
plugins.calc
有效。但是警告仍然存在:。\plugins\calc.py:6:RuntimeWarning:处理绝对导入时未找到父模块“plugins”time@alco谢谢你的解释。现在工作。