代码之家  ›  专栏  ›  技术社区  ›  Shane

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

  •  2
  • Shane  · 技术社区  · 15 年前

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

    3 回复  |  直到 15 年前
        1
  •  4
  •   volting    15 年前

    我建议你看看 threading module . 通过将 Thread 类可以为时间密集型作业创建新线程。

    然后,对于线程之间的通信,您可以使用 pubsub pydispatcher ,我没有尝试过后者,所以我不能对此发表评论,但我会推荐pubsub,因为它的易用性和它与wxpython的区别是一个额外的好处。

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


    下面是一个简单的(可运行的)示例,说明如何使用 pubsub 从您的工作线程向您的 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()
    
        2
  •  1
  •   Wai Yip Tung    15 年前

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

        3
  •  1
  •   Odomontois    15 年前
    推荐文章