Есть ли способ закрыть подпроцесс, когда я открываю его в предыдущем операторе if - PullRequest
0 голосов
/ 08 июля 2019

Я делаю скрипт на python, который открывает другой скрипт на Python, когда ему дана команда / starttest1, и я хочу закрыть его, когда команда равна / stoptest1

Я пытался использовать Popen.terminate (), но он выдал ошибку

if command == '/starttest1':
        extProc = sp.Popen(['python','haha.py'])
    elif command == '/stoptest1':
        sp.Popen.terminate(extProc)
        print("haha.py has been closed")

ошибка, с которой я столкнулся: UnboundLocalError: локальная переменная 'extProc', на которую ссылается перед присваиванием

В результате я хочу закрыть haha.py и напечатать "haha.py был закрыт"

Ответы [ 2 ]

0 голосов
/ 08 июля 2019

tl, dr: условные блоки не имеют значения. У них нет собственных пространств имен, поэтому у исключения есть и другие причины.

Условные блоки Python не имеют отдельных пространств имен. Вы можете получить доступ к любым переменным, определенным внутри условных блоков, как если бы они были определены в вашей обычной программе. Если условие не было выполнено и вы пытаетесь получить доступ к переменной, интерпретатор должен вызвать NameError. Так что вы можете просто сделать это:

if command == '/starttest1':
    extProc = sp.Popen(['python','haha.py'])
elif command == '/stoptest1':
    sp.Popen.terminate(extProc)
    print("haha.py has been closed")

В зависимости от того, кто использует ваш сценарий, вы можете добавить некоторую обработку для случая, когда extProc не существует, но приведенный выше код при копировании, вставленном в консоль Python, запускается и, если используется в правильном порядке, не будет поднимать никаких исключений. Я думаю, что ваша проблема в том, как этот код называется, поскольку вы наверняка не копируете его на консоль.

Вы можете попробовать то, что я называю "путь Java", и написать класс. Это IMO намного менее Pythonic, но он создает пространство имен вокруг вашего кода и допускает простую условную проверку, например:

class Handler(object):
    def __init__(self):
        self.extProc = None
    def do(self, command):
        if command == '/starttest1':
            extProc = sp.Popen(['python','haha.py'])
        elif command == '/stoptest1':
            if extProc is not None:
                sp.Popen.terminate(extProc)
                ectProc = None
                print("haha.py has been closed")
            else:
                handle_no_extProc()

Не используйте это в производительном коде, хотя (фактически, никогда не пишите классы только с одним методом, отличным от __init__), но это способ гарантировать, что условия не являются проблемой. Вы запускаете скрипт каждый раз, когда вводите новую команду? В этом случае нет возможности сохранить ссылки. Вы должны рассмотреть функцию input для получения новых команд и сохранения ваших ссылок. Единственный известный мне способ - это работать с низкоуровневыми вызовами os, но это, вероятно, не то, что вы ищете.

0 голосов
/ 08 июля 2019

Вы должны создать новый поток для процесса управления, например:

import subprocess as sp

process = None

def handler():
    global process
    if command == '/start'
        process = sp.Popen(['python','haha.py'])
    elif command == '/stop':
        if process is not None:
            sp.Popen.terminate(process) # terminate
        # e.g. else send error message "Process is not running"

Это не лучший пример, но хотя бы обратите внимание на значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...