Как управлять / вызывать другой скрипт на Python внутри одного скрипта?(Общение между сценариями) - PullRequest
2 голосов
/ 14 августа 2010

Я работаю над одной программой с графическим интерфейсом и собираюсь добавить долгосрочную задачу в одно событие, но я обнаружил, что это заставит всю программу сильно зависнуть, поэтому, учитывая советы других людей, я возьму на себя ответственность только за графический интерфейс.запуск, остановка, мониторинг и запуск долгосрочной задачи в виде отдельного сценария.Единственный способ, которым я знаю, чтобы запустить другой сценарий в одном сценарии, - это импорт, есть ли другие способы взаимодействия с другим сценарием, я имею в виду, например, чтение stdout другого и завершение его в любое время, когда вы хотите?

Ответы [ 3 ]

4 голосов
/ 14 августа 2010

Я предлагаю вам взглянуть на модуль потоков . Подклассы класса Thread позволяют создавать новые потоки для трудоемких заданий.

Тогда для связи между потоками вы можете использовать pubsub или pydispatcher , я не пробовал последнее, поэтому не могу комментировать, но я бы порекомендовал pubsub за простоту использования и тот факт, что кроме wxpython это бонус.

Здесь - это wiki-страница wxpython, посвященная выполнению длинных задач, пропустите ее до конца, если вы хотите самый простой пример использования потоков.


Вот простой (работающий) пример того, как вы могли бы использовать 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 голос
/ 14 августа 2010

Есть гораздо лучший способ сделать это, чем читать stdout: http://docs.python.org/library/multiprocessing.html

1 голос
/ 14 августа 2010

Если вам нужно общение с помощью stdin / stdout, вам следует использовать модуль subprocess.

...