终止Python脚本

Tei*_*ion 981 python termination

我知道die()PHP 中的命令可以提前停止脚本.

我怎么能用Python做到这一点?

pjz*_*pjz 1312

import sys
sys.exit()
Run Code Online (Sandbox Code Playgroud)

sys模块文档中的详细信息:

sys.exit([arg])

退出Python.这是通过引发SystemExit异常来实现的 ,因此最终的try语句子句指定的清理操作得到遵守,并且可以拦截外层的退出尝试.

可选参数arg可以是一个整数,给出退出状态(默认为零)或其他类型的对象.如果它是整数,则零被认为是"成功终止",并且任何非零值被贝壳等视为"异常终止".大多数系统要求它在0-127范围内,否则会产生不确定的结果.有些系统有一个约定,用于为特定的退出代码分配特定的含义,但这些通常是不发达的; Unix程序通常使用2表示命令行语法错误,1表示所有其他类型的错误.如果传递了另一种类型的对象,则None等效于传递零,并且打印任何其他对象stderr并导致退出代码为1.特别是 sys.exit("some error message") 发生错误时退出程序的快速方法.

由于exit()最终"only"引发了一个异常,它只会在从主线程调用时退出进程,并且异常不会被截获.

请注意,这是退出的"好方法".@ glyphtwistedmatrix低于指出,如果你想要一个"硬退出",你可以使用os._exit(错误代码),但它很可能与操作系统相关的在一定程度上(也许它不会在Windows下一个错误代码,例如),它肯定是不太友好,因为它不会让解释程序在进程死亡之前进行任何清理.

  • 有没有办法在不引发异常的情况下结束脚本?我已经将脚本中的相关标志传递给了pdn,并将stdout输出到了Popen中,因此这种情况下的异常会导致比解决方案更多的麻烦. (11认同)
  • 假设`sys.exit()`不起作用(不会杀死进程,只是杀死线程)如果由后台线程引发? (8认同)
  • 为什么,当我使用这种方法时,我会得到以下警告:```UserWarning:要退出:使用'exit','quit'或Ctrl-D.警告("退出:使用'退出','退出'或Ctrl-D.",stacklevel = 1)``` (4认同)
  • @cesium62:是的,“sys.exit()”在当前线程中引发“SystemExit”异常。 (2认同)
  • 如果您使用“Tkinter”,它不会停止根进程“mainLoop”及其显示的窗口。为此,您需要附加行“root.destroy()”。 (2认同)

j.m*_*g.r 307

提前终止Python脚本的一种简单方法是使用内置函数quit().无需导入任何库,它既高效又简单.

例:

#do stuff
if this == that:
  quit()
Run Code Online (Sandbox Code Playgroud)

  • sys.exit()也会终止所有python脚本,但是quit()只会终止产生它的脚本. (71认同)
  • 我在 python 3.7 中,quit() 停止解释器并关闭脚本。 (7认同)
  • 根据[文档](https://docs.python.org/3/library/constants.html#quit) `quit()` 是“*对于交互式解释器 shell 有用,不应该在程序中使用*。 ” (6认同)
  • 你知道这个命令在python 2和python 3中的工作方式是否有所不同? (4认同)
  • 对我来说,“退出”未定义。我正在使用python 3。 (2认同)

Vha*_*run 116

另一种方式是:

raise SystemExit
Run Code Online (Sandbox Code Playgroud)

  • @Alessa:它看起来更优雅,但不推荐:你直接提出内置异常而不是更好的(和可覆盖的)`sys.exit`包装器 (33认同)
  • 这对我来说是一个完美的方法:只需退出正在运行的脚本,但不退出 IDLE (5认同)

小智 66

你也可以简单地使用exit().

请记住sys.exit(),exit(),quit(),和os._exit(0) Python解释器.因此,如果它出现在从另一个脚本调用的脚本中execfile(),则会停止执行这两个脚本.

请参阅" 停止执行使用execfile调用的脚本 "以避免这种情况.

  • 对我来说 os._exit(0) 对我来说是最优雅的方式。所有其他人都提出了不需要的错误 (6认同)

Gly*_*yph 64

虽然你通常应该更喜欢,sys.exit因为它对其他代码更"友好",但实际上所做的只是引发异常.

如果你确定你需要立即退出一个进程,并且你可能在一个可以捕获的异常处理程序中,那么SystemExit还有另一个函数os._exit- 它会立即终止于C级并且不会执行任何正常的拆除翻译; 例如,不执行使用"atexit"模块注册的挂钩.

  • @bogdan.rusu, `os._exit()` 退出整个进程而不进行任何清理。由于在 AWS 中,正在运行的 VM 实例将在作业结束时被丢弃,因此这对我来说不是问题。 (2认同)

eay*_*din 29

我刚刚发现了写multithreadded的应用程序时,raise SystemExitsys.exit()两个只有杀死正在运行的线程.另一方面,os._exit()退出整个过程.这在这里讨论过.

以下示例有2个线程.肯尼和卡特曼.卡特曼应该永远活着,但肯尼被称为递归,并且应该在3秒后死亡.(递归调用不是最好的方法,但我有其他原因)

如果我们也希望卡特曼在肯尼去世时死去,肯尼应该离开os._exit,否则,只有肯尼会死,卡特曼将永远活着.

import threading
import time
import sys
import os

def kenny(num=0):
    if num > 3:
        # print("Kenny dies now...")
        # raise SystemExit #Kenny will die, but Cartman will live forever
        # sys.exit(1) #Same as above

        print("Kenny dies and also kills Cartman!")
        os._exit(1)
    while True:
        print("Kenny lives: {0}".format(num))
        time.sleep(1)
        num += 1
        kenny(num)

def cartman():
    i = 0
    while True:
        print("Cartman lives: {0}".format(i))
        i += 1
        time.sleep(1)

if __name__ == '__main__':
    daemon_kenny = threading.Thread(name='kenny', target=kenny)
    daemon_cartman = threading.Thread(name='cartman', target=cartman)
    daemon_kenny.setDaemon(True)
    daemon_cartman.setDaemon(True)

    daemon_kenny.start()
    daemon_cartman.start()
    daemon_kenny.join()
    daemon_cartman.join()
Run Code Online (Sandbox Code Playgroud)

  • 这似乎是处理令人讨厌的延迟回调的唯一方法!(即多线程方法。) (3认同)
  • 做得好。其他答案都没有直接解决多个线程,只有脚本生成其他脚本。 (3认同)

cle*_*leg 27

from sys import exit
exit()
Run Code Online (Sandbox Code Playgroud)

作为参数,您可以传递退出代码,退出代码将返回给操作系统.默认值为0.

  • 只是为了上面评论的后代 - `exit()` 和 `sys.exit()` 不是一回事。不要在脚本中使用内置的 `exit()`,这只是交互式 shell 的一个助手 - 使用 `sys.exit()` (9认同)
  • 就我而言,我什至不需要导入出口。 (2认同)

Art*_*yan 18

问题

在我的实践中,甚至存在一种情况,需要从其中一个进程中终止整个多处理器应用程序。

如果您的应用程序使用唯一的主进程,则以下函数可以很好地工作。但以下功能没有一个在我的情况下不起作用,因为应用程序还有许多其他活动进程。

  • quit()
  • exit(0)
  • os._exit(0)
  • sys.exit(0)
  • os.kill(os.getppid(), 9)-父进程的pidos.getppid()在哪里

最后一个进程杀死了主进程及其自身,但其余进程仍然存在。

解决方案

我不得不通过外部命令杀死它,最后使用 找到了解决方案pkill

import os

# This can be called even in process worker and will kill
# whole application included correlated processes as well
os.system(f"pkill -f {os.path.basename(__file__)}")
Run Code Online (Sandbox Code Playgroud)

  • 您的确切代码对我不起作用,但您为我指出了正确的方向: os.system("pkill -f " + sys.argv[0]) (2认同)

Flo*_*rse 17

我是一个新手,但肯定是更干净,更有控制力

def main():
    try:
        Answer = 1/0
        print  Answer
    except:
        print 'Program terminated'
        return
    print 'You wont see this'

if __name__ == '__main__': 
    main()
Run Code Online (Sandbox Code Playgroud)

...

程序终止

import sys
def main():
    try:
        Answer = 1/0
        print  Answer
    except:
        print 'Program terminated'
        sys.exit()
    print 'You wont see this'

if __name__ == '__main__': 
    main()
Run Code Online (Sandbox Code Playgroud)

...

程序终止跟踪(最近一次调用最后一次):文件"Z:\ Directory\testdieprogram.py",第12行,在main()文件"Z:\ Directory\testdieprogram.py",第8行,在主sys.exit中( )SystemExit

编辑

关键是程序平稳而平静地结束,而不是"我已经停止!!!!"

  • 一个问题是,如果你在嵌套函数中并且只想退出,你要么必须一直发送一个标志回到顶部函数,否则你将只返回到下一级别. (19认同)
  • 如果您试图建议您可以使用`return`来终止脚本,这绝对是一个废话.所有`return`正在做的是返回一个值和一个控制流到调用函数.在调用`return`函数后,它继续执行.当然,如果`return`是脚本中的最后一个语句,就像在你的例子中那样,那么脚本在调用后立即终止. (11认同)
  • 这种方法有一个强有力的论据:(1)从中间“退出”可以说是“转到”,因此是一种自然的厌恶;(2) 图书馆中的“退出”绝对是不好的做法(并且_任何东西_都可以成为图书馆),因为_图书馆_认为“不可恢复”的东西通常对_调用者_来说是好的。(注意:对于 C/C++/Java 开发人员总是不恰当地调用 `exit` 的 C/C++/Java 开发人员来说,使用异常退出是一种 Python 实用的解决方法——因此 Python 程序员可能不会注意到这段代码的恶臭);最后,(3) 多线程代码(pythonistas 历史上忽略了)。 (3认同)
  • 这是一种在哲学上不同的方法 - OP 询问如何“尽早”停止脚本;这个答案是说“不要”:包含一个优雅地完成的路径,将控制权返回到“main”方法并运行到完成。我认为这种方法在可用时应该是首选。 (2认同)

Dav*_* C. 7

在Python 3.5中,我尝试在不使用模块(例如sys,Biopy)的情况下合并类似的代码,而不是内置的内容来停止脚本并向用户输出错误消息.这是我的例子:

## My example:
if "ATG" in my_DNA: 
    ## <Do something & proceed...>
else: 
    print("Start codon is missing! Check your DNA sequence!");
    exit(); ## as most folks said above
Run Code Online (Sandbox Code Playgroud)

后来,我发现抛出错误更简洁:

## My example revised:
if "ATG" in my_DNA: 
    ## <Do something & proceed...>
else: 
    raise ValueError("Start codon is missing! Check your DNA sequence!");
Run Code Online (Sandbox Code Playgroud)