终止Python脚本

时间:2008-09-16 15:35:56

标签: python termination

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

我怎样才能在Python中执行此操作?

11 个答案:

答案 0 :(得分:1194)

import sys
sys.exit()

详情来自sys module documentation

  

sys.exit([arg])

     
    

退出Python。这是通过提高来实现的     SystemExit异常,所以finally子句指定的清理操作     try个陈述受到尊重,并且可以拦截     退出尝试在外层。

         

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

         

由于exit()最终“仅”会引发异常,因此它只会退出     从主线程调用时的进程,而异常则不是     截获。

  

请注意,这是退出的“好方法”。 @ glyphtwistedmatrix下面指出,如果你想要一个'硬退出',你可以使用os._exit( errorcode ),尽管它在某种程度上可能是特定于os的(可能不需要例如,在Windows下的错误代码,它肯定不太友好,因为它不会让解释器在进程死亡之前进行任何清理。

答案 1 :(得分:265)

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

示例:

#do stuff
if this == that:
  quit()

答案 2 :(得分:109)

另一种方式是:

raise SystemExit

答案 3 :(得分:62)

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

如果您确定需要立即退出进程,并且可能在某个异常处理程序内部会捕获SystemExit,则还有另一个函数 - os._exit - 它会立即终止C级并且不执行任何解释器的正常拆卸;例如,不会执行使用“atexit”模块注册的挂钩。

答案 4 :(得分:59)

您也可以使用exit()

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

请参阅“Stop execution of a script called with execfile”以避免这种情况。

答案 5 :(得分:26)

from sys import exit
exit()

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

答案 6 :(得分:22)

我刚刚发现,在编写多线程应用时,raise SystemExitsys.exit()都只会杀死正在运行的线程。另一方面,os._exit()退出整个过程。讨论了here.

以下示例有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()

答案 7 :(得分:16)

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

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行,主要         sys.exit()SystemExit

  

修改

关键是该计划平稳而平和地结束,而不是"我已经停止!!!!"

答案 8 :(得分:6)

在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!");

答案 9 :(得分:0)

有几种标准方法可以实现:

import sys
sys.exit(404)

# or...
exit(404)

# or...
quit(404)

# or...
raise SystemExit(404)

我不满意(至少在repl.it上)没有一个完全关闭翻译器;即使在exit之后,它也可以始终在repl中运行代码。我能想到的唯一始终阻止解释器继续进行的方法是通过休眠模拟系统退出。

import time
def forceStop(errmsg="emergency stop deployed. :("):
    print(f"\033[31m{errmsg}\033[0m")
    time.sleep(10000000)

显然不建议这样做。

答案 10 :(得分:-1)

我的两分钱。

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.')