1261

我知道die()PHP 中的命令会提前退出脚本。

我怎样才能在 Python 中做到这一点?

4

12 回答 12

1648
import sys
sys.exit()

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

sys.exit([arg])

退出 Python。这是通过引发 SystemExit异常来实现的,因此由语句的 finally 子句指定的清理操作try得到尊重,并且可以在外部级别拦截退出尝试。

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

由于exit()最终“only”引发了异常,所以只有在主线程调用时才会退出进程,异常不会被拦截。

请注意,这是退出的“好”方式。下面的@ glyphtwistedmatrix指出,如果你想要一个“硬退出”,你可以使用os._exit(*errorcode*),尽管它在某种程度上可能是特定于操作系统的(例如,它可能不会在 Windows 下使用错误代码),而且它肯定不太友好,因为它不允许解释器在进程终止之前进行任何清理。另一方面,它确实杀死了整个进程,包括所有正在运行的线程,而sys.exit()(如文档中所说)仅在从主线程调用时才退出,没有其他线程在运行。

于 2008-09-16T15:36:36.680 回答
455

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

例子:

#do stuff
if this == that:
  quit()
于 2013-02-12T15:50:06.713 回答
138

另一种方法是:

raise SystemExit
于 2008-09-16T15:37:13.763 回答
96

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

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

请参阅“停止执行使用 execfile 调用的脚本”来避免这种情况。

于 2013-04-22T14:57:00.843 回答
75

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

如果您确定需要立即退出进程,并且您可能处于某个会捕获的异常处理程序中,那么SystemExit还有另一个函数 -os._exit在 C 级别立即终止并且不执行任何正常的拆卸口译员;例如,使用“atexit”模块注册的钩子不会被执行。

于 2008-09-16T20:08:04.500 回答
67

我刚刚发现在编写多线程应用程序时,raise SystemExit两者sys.exit()都只杀死正在运行的线程。另一方面,os._exit()退出整个过程。这在“为什么 sys.exit() 在 Python 中的线程内调用时不退出? ”中进行了讨论。

下面的示例有 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()
于 2016-11-10T10:59:45.547 回答
36
from sys import exit
exit()

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

于 2008-09-16T15:38:28.877 回答
21

我是一个新手,但肯定这更干净,更可控

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

if __name__ == '__main__': 
    main()

...

程序终止

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()

...

程序终止的回溯(最后一次调用):文件“Z:\Directory\testdieprogram.py”,第 12 行,在 main() 文件“Z:\Directory\testdieprogram.py”,第 8 行,在 main sys.exit( ) 系统退出

编辑

关键是节目顺利而和平地结束,而不是“我已经停止了!!!!”

于 2014-03-19T11:13:22.700 回答
10

在 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

后来,我发现只是抛出一个错误更简洁:

## My example revised:
if "ATG" in my_DNA: 
    ## <Do something & proceed...>
else: 
    raise ValueError("Start codon is missing! Check your DNA sequence!")
于 2016-12-27T18:12:16.587 回答
3

问题

在我的实践中,甚至有必要从其中一个进程中终止整个多处理器应用程序。

如果您的应用程序仅使用主进程,则以下功能运行良好。但是在我的情况下,以下功能中没有一个不起作用,因为该应用程序还有许多其他活动进程。

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

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

解决方案

我不得不通过外部命令杀死它,最后找到了使用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__)}")
于 2022-01-22T10:06:16.220 回答
2

我的两分钱。

Python 3.8.1,Windows 10,64 位。

sys.exit()不直接为我工作。

我有几个下一个循环。

首先我声明一个布尔变量,我称之为immediateExit.

所以,在我写的程序代码的开头:

immediateExit = False

然后,从最内部(嵌套)循环异常开始,我写:

            immediateExit = True
            sys.exit('CSV file corrupted 0.')

然后我进入外循环的直接延续,在代码执行任何其他操作之前,我写:

    if immediateExit:
        sys.exit('CSV file corrupted 1.')

根据复杂性,有时上述语句也需要在除部分等中重复。

    if immediateExit:
        sys.exit('CSV file corrupted 1.5.')

自定义消息也用于我的个人调试,因为数字用于相同目的 - 查看脚本真正退出的位置。

'CSV file corrupted 1.5.'

在我的特殊情况下,我正在处理一个 CSV 文件,如果软件检测到它已损坏,我不希望软件触摸它。因此对我来说,在检测到可能的损坏后立即退出整个 Python 脚本非常重要。

并且在我设法做到的所有循环中逐渐退出系统。

完整代码:(需要进行一些更改,因为它是内部任务的专有代码):

immediateExit = False
start_date = '1994.01.01'
end_date = '1994.01.04'
resumedDate = end_date


end_date_in_working_days = False
while not end_date_in_working_days:
    try:
        end_day_position = working_days.index(end_date)

        end_date_in_working_days = True
    except ValueError: # try statement from end_date in workdays check
        print(current_date_and_time())
        end_date = input('>> {} is not in the list of working days. Change the date (YYYY.MM.DD): '.format(end_date))
        print('New end date: ', end_date, '\n')
        continue


    csv_filename = 'test.csv'
    csv_headers = 'date,rate,brand\n' # not real headers, this is just for example
    try:
        with open(csv_filename, 'r') as file:
            print('***\nOld file {} found. Resuming the file by re-processing the last date lines.\nThey shall be deleted and re-processed.\n***\n'.format(csv_filename))
            last_line = file.readlines()[-1]
            start_date = last_line.split(',')[0] # assigning the start date to be the last like date.
            resumedDate = start_date

            if last_line == csv_headers:
                pass
            elif start_date not in working_days:
                print('***\n\n{} file might be corrupted. Erase or edit the file to continue.\n***'.format(csv_filename))
                immediateExit = True
                sys.exit('CSV file corrupted 0.')
            else:
                start_date = last_line.split(',')[0] # assigning the start date to be the last like date.
                print('\nLast date:', start_date)
                file.seek(0) # setting the cursor at the beginnning of the file
                lines = file.readlines() # reading the file contents into a list
                count = 0 # nr. of lines with last date
                for line in lines: #cycling through the lines of the file
                    if line.split(',')[0] == start_date: # cycle for counting the lines with last date in it.
                        count = count + 1
        if immediateExit:
            sys.exit('CSV file corrupted 1.')
        for iter in range(count): # removing the lines with last date
            lines.pop()
        print('\n{} lines removed from date: {} in {} file'.format(count, start_date, csv_filename))



        if immediateExit:
            sys.exit('CSV file corrupted 1.2.')
        with open(csv_filename, 'w') as file:
            print('\nFile', csv_filename, 'open for writing')
            file.writelines(lines)

            print('\nRemoving', count, 'lines from', csv_filename)

        fileExists = True

    except:
        if immediateExit:
            sys.exit('CSV file corrupted 1.5.')
        with open(csv_filename, 'w') as file:
            file.write(csv_headers)
            fileExists = False
    if immediateExit:
        sys.exit('CSV file corrupted 2.')

于 2020-03-22T21:50:27.977 回答
0

只需放在代码的末尾,quit()这应该会关闭一个 python 脚本。

于 2022-01-23T17:32:37.613 回答