当我在上一个if语句中打开子流程时,有没有办法关闭它

时间:2019-07-08 08:06:40

标签: python subprocess

我正在做一个python脚本,当给定/ starttest1命令时,它会打开另一个python脚本,而我想在命令为/ 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 :(得分:0)

您应该为控制过程创建新线程,例如:

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"

这不是最好的例子,但至少要注意含义。

答案 1 :(得分:0)

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少了Python风格,但它在代码周围创建了一个名称空间,并允许像这样的简单条件检查:

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-calls,但这可能不是您想要的。