- Как запускать внешние процессы, используя Python
- Синтаксис subprocess.run
- Обработка исключений
- Ограничение времени выполнения
- Функция subprocess.run
- Заключение
- Python запускает другой скрипт Python
- Используйте оператор import для запуска сценария Python в другом сценарии Python
- Используйте метод execfile() для запуска скрипта Python в другом скрипте Python
- Используйте модуль subprocess для запуска скрипта Python в другом скрипте Python
Как запускать внешние процессы, используя Python
Современные облачные сервисы, например, cloud.timeweb.com , стали сегодня обыденностью. Удалённый доступ и удалённое управление – основа современного цифрового мира. В нашей сегодняшней статье мы расскажем вам, как запускать внешние процессы при помощи различных модулей в Python 3 .
Для запуска внешних программ из Python, а также получения их ввода или вывода используется встроенный модуль subprocess . Данный модуль позволяет запускать и контролировать выполнение различных программ, которые доступны на компьютере.
Чтобы запустить программу с помощью модуля subprocess можно использовать несколько функций: subprocess.run (пришла на замену функции subprocess.call() в версии Python 3.5) и subprocess.Popen.
Синтаксис subprocess.run
subprocess.run(args, *, stdin, input, stdout, stderr,
capture_output, shell, cwd, timeout,
check, encoding, errors, text, env,
universal_newlines)
Аргумент args – обязательный, через него передается запускаемая программа с аргументами.
Параметры stdin , input , stdout и stderr отвечают за потоки данных, которые передаются в процесс или выходят из него. Здесь stdout — поток вывода (результат работы), stderr — поток ошибок, которые возникли при выполнении. По умолчанию их значения — None.
capture_output — по умолчанию False, отвечает за захват результата работы процесса (вывода).
Параметр shell отвечает за способ передачи в процесс программы и ее аргументов — если они представлены как одна строка, следует указать True. По умолчанию False.
cwd — используется, если требуется указать абсолютный путь к каталогу с запускаемой программой.
timeout — время в секундах, по истечении которого процесс завершится. При этом возникает исключение.
check — если имеет значение True, то вызывает исключение, если во время выполнения возникли ошибки. По умолчанию False.
encoding — отвечает за декодирование вывода.
errors — если указан, то ошибки кодировки будут вызывать исключение.
text , universal_newlines — текстовые режимы для потоков ввода, вывода и ошибок. По умолчанию false.
env — переменные среды для нового процесса.
Функция возвращает объект CompletedProcess , содержащий результаты работы. С помощью специальных атрибутов можно получить из этого объекта переданные в функцию аргументы, код результата выполнения, вывод или возникшие ошибки. Работая с этой функцией, необходимо аккуратно работать с кодом из ненадёжных источников, потому что она может выполнять всё подряд, особенно в случае запуска от имени администратора.
Перед тем как рассматривать примеры, импортируем необходимые модули:
from subprocess import run, Popen, PIPE
from sys import executable
python import local file
Значение executable в Python — это абсолютный путь к исполняемому файлу интерпретатора Python. Оно потребуется для запуска кода.
Рассмотрим простой пример применения CompletedProcess .
run("echo 'Subprocesses are cool!", shell=True)
Результатом работы будет объект:
CompletedProcess(args="echo 'Subprocesses are cool!", returncode=0)
Здесь мы видим переданные нами аргументы и статус выполнения ( returncode ). Когда статус выполнения равен нулю, это означает, что выполнение завершено успешно.
Рассмотрим сценарий сложнее. В предыдущем примере мы просто запустили внешний процесс и получили ответ, что он успешно выполнен. Но что если мы хотим получить не только статус выполнения, но и какие-то данные вывода? Для этого нам необходимо установить параметр capture_output = True :
run('ping localhost', shell = True, capture_output = True, encoding='cp866')
В этом примере мы отправляем запрос на localhost для проверки соединения. Параметр encoding указывает, что нам нужно декодировать результат, иначе мы получим его как байтовую строку.
Чтобы получить вывод программы и ошибки, выполним:
print("stdout:", result.stdout)
print("stderr:", result.stderr)
stdout:
Обмен пакетами с DESKTOP-*** [::1] с 32 байтами данных:
Ответ от ::1: времяОтвет от ::1: времяОтвет от ::1: времяОтвет от ::1: время
stderr:
В случае, если во время выполнения возникла какая-то ошибка, подпроцесс вернет ее в result.stderr . В данном случае ошибок не возникло.
Обработка исключений
run([executable, "-c", "raise ValueError('It seems there is a mistake!')"], capture_output=True, encoding='cp866')
Элемент -c – это опция командной строки python, позволяющая передавать на ввод целую программу.
Он сработает без проблем, однако если мы захотим вывести stdout , то увидим, что он пустой (в отличие от stderr ).
stdout:
stderr: Traceback (most recent call last):
File "", line 1, in
ValueError: It seems there is a mistake!
Если вызвать метод check_returncode , то мы увидим следующее:
CalledProcessError: Command '['D:\\***\\python.exe', '-c', "raise ValueError('It seems there is a mistake!')"]' returned non-zero exit status 1.
Мы получили ошибку. Для того, чтобы исключение возникало на этапе выполнения подпроцесса, необходимо указать параметр check = True .
В этом случае код не выполнится, и мы сразу будем знать, что в процессе возникла какая-то проблема.
Ограничение времени выполнения
Мы можем включить ограничение времени выполнения подпроцесса, чтобы программа, которая работает некорректно, не исполнялась бесконечно. Для этого используется параметр timeout :
run('ping yandex.ru', shell = True, timeout=5, capture_output = True, encoding='cp866')
В случае, если команда выполнилась, мы получим ее вывод:
Обмен пакетами с yandex.ru [77.88.55.50] с 32 байтами данных:
Ответ от 77.88.55.50: число байт=32 время=17мс TTL=56
Ответ от 77.88.55.50: число байт=32 время=17мс TTL=56
Ответ от 77.88.55.50: число байт=32 время=17мс TTL=56
Ответ от 77.88.55.50: число байт=32 время=17мс TTL=56
Если же наша команда не успела закончить выполнение за отведенное время, мы получаем исключение:
TimeoutExpired: Command 'ping yandex.ru' timed out after 1 seconds
С помощью подпроцессов мы также можем запускать установленные программы. Например:
Также мы можем передавать какой-либо ввод используя stdin и параметр input . Выполним код:
run([executable, "-c", "from sys import stdin; print(stdin.read())"], input="Hello subprocess!",capture_output=True, encoding='cp866')
Через Input можно передавать не только определенный текст, но и вывод программы.
Функция subprocess.run
Функция run модуля Subprocess является высокоуровневой. Если для нашей задачи требуется бо́льшая гибкость, то можно использовать напрямую класс Popen. Он имеет схожий синтаксис, однако у него есть несколько дополнительных параметров.
Создадим 2 подпроцесса. В первом мы получим содержимое папки, а с помощью второго выполним сортировку. Чтобы использовать вывод результата первого подпроцесса, мы указываем для него stdout=PIPE (это значение, которое можно использовать в качестве аргумента для stdin , stdout или stderr ).
Чтобы создать связь между двумя процессами, используется метод communicate() .
p1 = Popen('dir', shell=True, stdin=None, stdout=PIPE, stderr=PIPE)
p2 = Popen('sort /R', shell=True, stdin=p1.stdout)
p1.stdout.close()
out, err = p2.communicate()
Результатом работы этого кода будет вывод отсортированных файлов в папке:
21.03.2022 12:35 ..
21.03.2022 12:35 .
21.03.2022 12:35 256 test1.py
21.03.2022 12:34 255 test3.py
21.03.2022 12:21 247 test5.py
21.03.2022 12:21 247 test4.py
21.03.2022 12:21 247 test2.py
21.03.2022 12:21 247 test.py
Класс Popen имеет также несколько других полезных методов:
- poll() — проверяет, завершён ли дочерний процесс. Возвращает либо код выполнения, либо None, если процесс еще выполняется.
- wait(timeout=None) — ждет завершения дочернего процесса, если указан timeout, то завершается по истечению указанного времени и вызывает исключение TimeoutExpired .
- terminate() — останавливает выполнение процесса.
Заключение
В сегодняшней статье мы рассмотрели, как, используя Python, запустить внешние процессы. Это стандартная возможность библиотеки Python, позволяющая запускать внешние программы и осуществлять вывод.
Python запускает другой скрипт Python
- Используйте оператор import для запуска сценария Python в другом сценарии Python
- Используйте метод execfile() для запуска скрипта Python в другом скрипте Python
- Используйте модуль subprocess для запуска скрипта Python в другом скрипте Python
Базовый текстовый файл, содержащий код Python, который предназначен для непосредственного выполнения клиентом, обычно называется сценарием, формально известным как программный файл верхнего уровня.
Скрипты предназначены для непосредственного выполнения на Python. Научиться запускать сценарии и код — это фундаментальный навык в мире программирования на Python. Скрипт Python обычно имеет расширение ‘.py’ . Если сценарий запускается на машине с Windows, он может иметь расширение .pyw .
В этом руководстве будут рассмотрены различные методы запуска сценария Python внутри другого сценария Python.
Используйте оператор import для запуска сценария Python в другом сценарии Python
Оператор import используется для импорта нескольких модулей в код Python. Он используется для получения доступа к определенному коду из модуля. Этот метод использует оператор import для импорта скрипта в код Python и использует его как модуль. Модули можно определить как файл, содержащий определения и инструкции Python.
В следующем коде оператор import используется для запуска сценария Python в другом сценарии Python.
def func1(): print ("Function 1 is active") if __name__ == '__main__': # Script2.py executed as script # do something func1()
import Script1.py def func2(): print("Function 2 is active") if __name__ == '__main__': # Script2.py executed as script # do something func2() Script1.func1()
Function 2 is active Function 1 is active
Используйте метод execfile() для запуска скрипта Python в другом скрипте Python
Функция execfile() выполняет в интерпретаторе нужный файл. Эта функция работает только в Python 2. В Python 3 функция execfile() была удалена, но то же самое можно сделать в Python 3 с помощью метода exec() .
# Python 2 code execfile("Script1.py")
Используйте модуль subprocess для запуска скрипта Python в другом скрипте Python
Модуль subprocess может порождать новые процессы, а также может возвращать их выходные данные. Это новый модуль, предназначенный для замены нескольких старых модулей, таких как os.system , которые ранее использовались для запуска сценария Python в другом сценарии Python.
def func1(): print ("Function 1 is active") if __name__ == '__main__': # Script2.py executed as script # do something func1()
import subprocess subprocess.call("Script1.py", shell=True)
Хотя все три метода работают нормально, этот метод имеет преимущество перед двумя другими методами. В этом методе не требуется редактировать существующий сценарий Python и помещать весь содержащийся в нем код в подпрограмму.
Vaibhhav is an IT professional who has a strong-hold in Python programming and various projects under his belt. He has an eagerness to discover new things and is a quick learner.