Passing data between separately running Python scripts Passing data between separately running Python scripts tkinter tkinter

Passing data between separately running Python scripts


you can use multiprocessing module to implement a Pipe between the two modules. Then you can start one of the modules as a Process and use the Pipe to communicate with it. The best part about using pipes is you can also pass python objects like dict,list through it.

Ex:mp2.py:

from multiprocessing import Process,Queue,Pipefrom mp1 import fif __name__ == '__main__':    parent_conn,child_conn = Pipe()    p = Process(target=f, args=(child_conn,))    p.start()    print(parent_conn.recv())   # prints "Hello"

mp1.py:

from multiprocessing import Process,Pipedef f(child_conn):    msg = "Hello"    child_conn.send(msg)    child_conn.close()


If you wanna read and modify shared data, between 2 scripts, which run separately, a good solution is, take advantage of the python multiprocessing module, and use a Pipe() or a Queue() (see differences here). This way, you get to sync scripts, and avoid problems regarding concurrency and global variables (like what happens if both scripts wanna modify a variable at the same time).

As Akshay Apte said in his answer, the best part about using pipes/queues, is that you can pass python objects through them.

Also, there are methods to avoid waiting for data, if there hasn't been any passed yet (queue.empty() and pipeConn.poll()).

See an example using Queue() below:

    # main.py    from multiprocessing import Process, Queue    from stage1 import Stage1    from stage2 import Stage2    s1= Stage1()    s2= Stage2()    # S1 to S2 communication    queueS1 = Queue()  # s1.stage1() writes to queueS1    # S2 to S1 communication    queueS2 = Queue()  # s2.stage2() writes to queueS2    # start s2 as another process    s2 = Process(target=s2.stage2, args=(queueS1, queueS2))    s2.daemon = True    s2.start()     # Launch the stage2 process    s1.stage1(queueS1, queueS2) # start sending stuff from s1 to s2     s2.join() # wait till s2 daemon finishes
    # stage1.py    import time    import random    class Stage1:      def stage1(self, queueS1, queueS2):        print("stage1")        lala = []        lis = [1, 2, 3, 4, 5]        for i in range(len(lis)):          # to avoid unnecessary waiting          if not queueS2.empty():            msg = queueS2.get()    # get msg from s2            print("! ! ! stage1 RECEIVED from s2:", msg)            lala = [6, 7, 8] # now that a msg was received, further msgs will be different          time.sleep(1) # work          random.shuffle(lis)          queueS1.put(lis + lala)                     queueS1.put('s1 is DONE')
    # stage2.py    import time    class Stage2:      def stage2(self, queueS1, queueS2):        print("stage2")        while True:            msg = queueS1.get()    # wait till there is a msg from s1            print("- - - stage2 RECEIVED from s1:", msg)            if msg == 's1 is DONE ':                break # ends loop            time.sleep(1) # work            queueS2.put("update lists")             

EDIT: just found that you can use queue.get(False) to avoid blockage when receiving data. This way there's no need to check first if the queue is empty. This is no possible if you use pipes.


You could use the pickling module to pass data between two python programs.

import pickle def storeData():     # initializing data to be stored in db     employee1 = {'key' : 'Engineer', 'name' : 'Harrison',     'age' : 21, 'pay' : 40000}     employee2 = {'key' : 'LeadDeveloper', 'name' : 'Jack',     'age' : 50, 'pay' : 50000}     # database     db = {}     db['employee1'] = employee1     db['employee2'] = employee2     # Its important to use binary mode     dbfile = open('examplePickle', 'ab')     # source, destination     pickle.dump(db, dbfile)                       dbfile.close() def loadData():     # for reading also binary mode is important     dbfile = open('examplePickle', 'rb')          db = pickle.load(dbfile)     for keys in db:         print(keys, '=>', db[keys])     dbfile.close()