如何在一个python脚本中控制/调用另一个python脚本? (脚本之间的通信)

时间:2010-08-14 05:13:45

标签: python event-handling wxpython

我正在开发一个GUI程序,并且会在一个事件中添加一个长时间运行的任务,但我发现这会使整个程序冻结很多,所以考虑到其他人的建议我会让GUI只负责启动,停止和监视并使长时间运行的任务作为单独的脚本运行。我知道在一个脚本中运行另一个脚本的唯一方法是导入,有没有其他方法与另一个脚本进行通信,我的意思是读取另一个stdout并在任何时候终止它?

3 个答案:

答案 0 :(得分:4)

我建议您查看threading module。通过子类化Thread类,您可以为时间密集型作业创建新线程。

然后,对于线程之间的通信,您可以使用pubsubpydispatcher,我没有尝试后者,所以我不能评论它,但我会推荐pubsub,因为它的易用性使用和wxpython的区别是奖金。

Here 是关于运行长任务的wxpython wiki页面,如果你想要最简单的线程示例用法,请跳到最后。


下面是一个简单(可运行)示例,说明如何使用pubsub将来自workerThread的邮件发送到GUI

import time

import wx
from threading import Thread
from wx.lib.pubsub import Publisher

class WorkerThread(Thread):
    def __init__(self):
        Thread.__init__(self)

        #A flag that can be set 
        #to tell the thread to end
        self.stop_flag = False

        #This calls the run() to start the new thread
        self.start()


    def run(self):
        """ Over-rides the super-classes run()"""
        #Put everything in here that 
        #you want to run in your new thread

        #e.g...
        for x in range(20):
            if self.stop_flag:
                break
            time.sleep(1)
            #Broadcast a message to who ever's listening
            Publisher.sendMessage("your_topic_name", x)
        Publisher.sendMessage("your_topic_name", "finished")


    def stop(self):
        """
        Call this method to tell the thread to stop
        """
        self.stop_flag = True




class GUI(wx.Frame):
    def __init__(self, parent, id=-1,title=""):
        wx.Frame.__init__(self, parent, id, title, size=(140,180))
        self.SetMinSize((140,180)) 
        panel = wx.Panel(id=wx.ID_ANY, name=u'mainPanel', parent=self)

        #Subscribe to messages from the workerThread
        Publisher().subscribe(self.your_message_handler, "your_topic_name")

        #A button to start the workerThread
        self.startButton = wx.Button(panel, wx.ID_ANY, 'Start thread')
        self.Bind(wx.EVT_BUTTON,  self.onStart, self.startButton)

        #A button to stop the workerThread
        self.stopButton = wx.Button(panel, wx.ID_ANY, 'Stop thread')
        self.Bind(wx.EVT_BUTTON,  self.onStop, self.stopButton)

        #A text control to display messages from the worker thread
        self.threadMessage = wx.TextCtrl(panel, wx.ID_ANY, '', size=(75, 20))

        #Do the layout
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.startButton, 0, wx.ALL, 10)
        sizer.Add(self.stopButton, 0, wx.ALL, 10)
        sizer.Add(self.threadMessage, 0, wx.ALL, 10)
        panel.SetSizerAndFit(sizer)


    def onStart(self, event):
        #Start the worker thread
        self.worker = WorkerThread()

        #Disable any widgets which could affect your thread
        self.startButton.Disable()

    def onStop(self, message):
        self.worker.stop()

    def your_message_handler(self, message):
        message_data = message.data
        if message_data == 'finished':
            self.startButton.Enable()
            self.threadMessage.SetLabel(str(message_data))
        else:
            self.threadMessage.SetLabel(str(message_data))

if __name__ == "__main__":

    app = wx.PySimpleApp()
    frame = GUI(None, wx.ID_ANY, 'Threading Example')
    frame.Show()
    app.MainLoop()

答案 1 :(得分:1)

如果你需要通过stdin / stdout进行通信,你应该使用subprocess模块。

答案 2 :(得分:1)

除了阅读标准输出:http://docs.python.org/library/multiprocessing.html

之外,还有更好的方法