问题:如何终止Python脚本
我知道die()
PHP 中的命令会较早退出脚本。
如何在Python中执行此操作?
回答 0
import sys
sys.exit()
sys
模块文档中的详细信息:
sys.exit([arg])
从Python退出。这是通过引发
SystemExit
异常来实现的,因此可以执行try
语句的finally子句指定的清除操作,并且有可能在外部级别拦截出口尝试。可选参数arg可以是给出退出状态的整数(默认为零),也可以是其他类型的对象。如果它是整数,则Shell等将零视为“成功终止”,而将任何非零值视为“异常终止”。大多数系统要求它的范围是0-127,否则会产生不确定的结果。某些系统具有为特定的退出代码分配特定含义的约定,但是这些通常不完善。Unix程序通常将2用于命令行语法错误,将1用于所有其他类型的错误。如果传递了另一种类型的对象,则“无”等效于传递零,并且将任何其他对象输出
stderr
并导致退出代码为1。特别是,sys.exit("some error message")
是发生错误时退出程序的快速方法。由于
exit()
最终“仅”会引发异常,因此它仅在从主线程调用时才退出进程,并且不会拦截该异常。
请注意,这是退出的“不错”方式。下面的@ glyphtwistedmatrix指出,如果您想要“硬出口”,则可以使用os._exit(*errorcode*)
,尽管它在某种程度上可能是特定于OS的(例如,在Windows下可能不会显示错误代码),并且它肯定不那么友好,因为它在进程终止之前,不允许解释器进行任何清理。
回答 1
一种提前终止Python脚本的简单方法是使用内置quit()
函数。无需导入任何库,它既高效又简单。
例:
#do stuff
if this == that:
quit()
回答 2
另一种方法是:
raise SystemExit
回答 3
您也可以简单地使用exit()
。
请记住sys.exit()
,exit()
,quit()
,和os._exit(0)
杀 Python解释器。因此,如果它出现在由另一个脚本通过调用的脚本中execfile()
,它将停止两个脚本的执行。
请参阅“ 停止执行用execfile调用的脚本 ”来避免这种情况。
回答 4
尽管您通常应该选择sys.exit
它是因为它比其他代码更“友好”,但它实际上所做的只是引发一个异常。
如果您确定需要立即退出进程,并且您可能在某个将捕获的异常处理程序中SystemExit
,则可以使用另一个函数– os._exit
在C级别立即终止,并且不执行任何正常的删除操作口译员 例如,不执行在“ atexit”模块中注册的钩子。
回答 5
我刚刚发现了写multithreadded的应用程序时,raise SystemExit
和sys.exit()
两个只有杀死正在运行的线程。另一方面,os._exit()
退出整个过程。在“ 为什么在Python的线程内调用sys.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()
回答 6
from sys import exit
exit()
作为参数,您可以传递退出代码,该退出代码将返回给OS。默认值为0。
回答 7
我是一个新手,但可以肯定的是,它更干净,更易控制
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()
…
程序终止了回溯(最近一次调用最后一次):main()中的文件“ Z:\ Directory \ testdieprogram.py”,第12行,sys.exit中主要的文件“ Z:\ Directory \ testdieprogram.py”,第8行( )SystemExit
编辑
关键是该程序可以顺利,和平地结束,而不是“我已停止!!!!”
回答 8
在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
我的两分钱。
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.')