- Как в Python передавать данные из одного скрипта в другой?
- Войдите, чтобы написать ответ
- Почему бот не переходит в другую функцию после нажатия на inline_button?
- Связь между программами python
- 1 ответ 1
- Passing data between separately running Python scripts
- 5 Answers 5
- Обмен данными между двумя python скриптами
- 1 ответ 1
Как в Python передавать данные из одного скрипта в другой?
Есть скрипт №1, выполняющий роль API на сервере. Работает постоянно. При определенных запросах скрипт №1 должен запускать скрипт №2 и передавать ему определенные данные, которые скрипт №2 обработает и сделает определенные действия. Если коротко, скрипт №1 запускает скрипт №2 и говорит ему «На тебе вот эти данные, делай с ними что хочешь»=)). Как это реализовать?
Простой 1 комментарий
а просто передать через файл не получается ? ну может не файл а пайп или сокет ?
или можно просто открыть дочерний процесс и напрямую писать в его входной поток.
Скрипт №1 добавляет задачу, скрипт №2 получает ее и выполняет необходимые действия
Когда устанешь разбирать с селерами, рэббитами, и прочей ненужной дичью, просто открой доку питона и прочитай про мультипроцессинг
https://docs.python.org/3/library/multiprocessing.html
а в описании Celery мы видим такие штуки — RabbitMQ и Redis, вот если не нужна функциональность Celery, то можно этими ребятами пользоваться (Есть еще некоторое количество брокеров сообщений, можно погуглить) И если Redis — это всетаки БД, просто с опцией публикации и чтения данных (как каналы в телеграм, можно опубликовать что то, а подписанные на получение скрипты это получат), то Rabbit предназначен ровно для обмена данными между двумя приложениями, в том числе и скриптами Python
В общем, используется IPC.
Часто для таких вещей используются очереди. Например, ZeroMQ или что-то другое, например, популярный RabbitMQ.
Войдите, чтобы написать ответ
Почему бот не переходит в другую функцию после нажатия на inline_button?
Связь между программами python
Есть две программы написанные на python. Как из первой программы направить запрос во вторую? То есть условно говоря первая программа отправляет текст «Hello, world!», а вторая его получает и выводит на экран UPD 1: Я не имею в виду работу с библиотекой socket и ей подобными UPD 2: Обе программы запускаются на одном компьютере UPD 3: Я не имею ввиду работу с импортами
Зависит от той программы, которая должна принять информацию. В ней должен быть явно написан код который откуда то получает данные. И если там такое предусмотрено, то надо посмотреть как именно она готова получать данные. Ответ на ваш вопрос невозможен без просмотра кода программ
В любом уважающем себя интерпретаторе команд есть возможность перенаправить вывод одной программы в ввод другой программы python программа1.py | python программа2.py
@andreymal, да, но как это сделать? как написать первую и вторую программы чтобы они могли ‘общаться’ между собой
вот вам две программы, одна передаёт другой строку 12 , вторая преобразует строку в число, прибавляет единицу, и печатает результат: $ python3 -c ‘print(12)’ | python3 -c ‘x=int(input());print(x+1)’ . но это одностороннее общение. про двустороннее — ссылку на википедию привёл Mike.
1 ответ 1
Под вопросом «Как сделать запрос во вторую программу?» я наверное понял, как вам из одной программы достать переменную/вызвать функцию из другой программы.
Я пишу код для примера, а автор вопроса уже сам адаптирует его под себя:
#main1.py def func(): int1 = 10 print(int1)
#main2.py from main1 import func func()
Есть несколько примечаний:
- Оба .py файла должны быть в одной папке (если они в разных папках, то нужно импортировать уже из папки так):
#C:\Users\[имя пользователя]\Dekstop\testfolder\main1.py def func(): int1 = 10 print(int1)
#C:\Users\[имя пользователя]\Desktop\main2.py from testfolder.main1 import func func()
#main1.py from main2 import func2 def func1(): int1 = 10 print(int1)
#main2.py from main1 import func1 def func2(): int2 = 20 print(int2)
Если так сделать, то смотря с какого файла ты запустишь программу вылезет такая ошибка:
ImportError: cannot import name 'main1' from partially initialized module 'main2' (most likely due to a circular import)
- Если Вы собрались компилировать программу через pyinstaller в один .exe файл, то не забудьте прописать это:
pyinstaller --onefile main1.py -p main2.py
Первое название файла после —onefile будет выступать некой «точкой запуска», то есть файл main1.py будет являться основной программой. Имейте это в виду.
Надеюсь, автор получил тот ответ, который хотел.
Passing data between separately running Python scripts
If I have a python script running (with full Tkinter GUI and everything) and I want to pass the live data it is gathering (stored internally in arrays and such) to another python script, what would be the best way of doing that? I cannot simply import script A into script B as it will create a new instance of script A, rather than accessing any variables in the already running script A. The only way I can think of doing it is by having script A write to a file, and then script B get the data from the file. This is less than ideal however as something bad might happen if script B tries to read a file that script A is already writing in. Also I am looking for a much faster speed to communication between the two programs. EDIT: Here are the examples as requested. I am aware why this doesn’t work, but it is the basic premise of what needs to be achieved. My source code is very long and unfortunately confidential, so it is not going to help here. In summary, script A is running Tkinter and gathering data, while script B is views.py as a part of Django, but I’m hoping this can be achieved as a part of Python. Script A
import time i = 0 def return_data(): return i if __name__ == "__main__": while True: i = i + 1 print i time.sleep(.01)
import time from scriptA import return_data if __name__ == '__main__': while True: print return_data() # from script A time.sleep(1)
You should be able to import one module to the other, instantiate a single instance (using a singleton if necessary) and then assign attributes/values to this instance so you can read from it as needed in the secondary script.
The question is to vague. «pass the live data to another script» could mean many different things. How are you passing it? Over a socket? via a restful interface? As command line arguments? Do you pass the data once when starting the second program or is the data constantly updated as it changes? Please show a Minimal, Complete, and Verifiable example
5 Answers 5
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.
from multiprocessing import Process,Queue,Pipe from mp1 import f if __name__ == '__main__': parent_conn,child_conn = Pipe() p = Process(target=f, args=(child_conn,)) p.start() print(parent_conn.recv()) # prints "Hello"
from multiprocessing import Process,Pipe def f(child_conn): msg = "Hello" child_conn.send(msg) child_conn.close()
This seems to be the way to go, however why doesn’t the following work? If you add this code to the end of mp1.py: i = 0 def g(): print i if __name__ == «__main__»: while True: i = i + 1 g() Why doesn’t running mp2.py return the current i?
Didn’t quite understand your question there. however if you want to call the function g(), you need to specify it in p = Process(target=g, args=(child_conn,))
See examples in edit, if you insert your code into them, mp2 will return 0 rather than whatever i is at in mp1.
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.
Обмен данными между двумя python скриптами
Суть Первый скрипт запускается, ищет доступные последовательные порты и складывает в список, передаёт их другому скрипту, а далее перезагружается(не смог заставить serial.tools.list_ports искать порты в цикле).Второй скрипт принимает список и уже применяет в некоторых целях. Вопрос, как реализовать связь между скриптами, при условии, что один из них будет постоянно перезагружаться. Если есть возможность не перезагружать первый скрипт, а искать порты в цикле, так даже будет лучше Вот пример кода:
import serial.tools.list_ports port_list = [] def search_ports(): ports = serial.tools.list_ports.comports() for port, desc, hwid in sorted(ports): port_list.append(port) search_ports()
А почему бы не использовать для этого какую-нибудь примитивную БД хотя бы sqlite для примера. В теории конечно можно налепить сокетов, но нафига?
«а искать порты в цикле,» — ну так ищите в цикле. В чем проблема вызывать хотя бы search_ports() сколько угодно раз?
@vitidev, Я так понял этот модуль сканирует порты при запуске скрипта.В цикле он кидает те же порты снова и снова,хотя добавились новые
1 ответ 1
Как оказалось этот модуль верно сканирует все порты в цикле, ошибка была в последующей части кода, там я записал новые порты в другую переменную с похожим названием, которую не обновлял для виджета OptionMenu
import serial.tools.list_ports port_list = [] def search_ports(): ports = serial.tools.list_ports.comports() for port, desc, hwid in sorted(ports): port_list.append(port) search_ports() # появился новый порт # используем вторую функцию def common(): ports = serial.tools.list_ports.comports() # for port, desc, hwid in sorted(ports): # Инициализация портов(разделение строки) if port_list.count(port) == 0: port_list.append(port) else: continue menu = your_option_menu["menu"] menu.delete(0, "end") for string in port_list: menu.add_command(label=string, command=lambda value=string:your_string_var.set(value)) print(port_list) common()