如何终止脚本?

发布于 2024-07-06 09:33:10 字数 48 浏览 11 评论 0原文

如何提前退出脚本,例如 PHP 中的 die() 命令?

How do I exit a script early, like the die() command in PHP?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

醉酒的小男人 2024-07-13 09:33:10
import sys
sys.exit()

详细信息来自 sys 模块文档 :

sys.退出([arg])

退出Python。 这是通过提高
SystemExit 异常, so 由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()(正如文档中所述)仅在调用时退出主线程,没有其他线程在运行。

import sys
sys.exit()

details from the sys module documentation:

sys.exit([arg])

Exit from Python. This is implemented by raising the
SystemExit exception, so cleanup actions specified by finally clauses
of try statements are honored, and it is possible to intercept the
exit attempt at an outer level.

The optional argument arg can be an integer giving the exit status
(defaulting to zero), or another type of object. If it is an integer,
zero is considered “successful termination” and any nonzero value is
considered “abnormal termination” by shells and the like. Most systems
require it to be in the range 0-127, and produce undefined results
otherwise. Some systems have a convention for assigning specific
meanings to specific exit codes, but these are generally
underdeveloped; Unix programs generally use 2 for command line syntax
errors and 1 for all other kind of errors. If another type of object
is passed, None is equivalent to passing zero, and any other object is
printed to stderr and results in an exit code of 1. In particular,
sys.exit("some error message") is a quick way to exit a program when
an error occurs.

Since exit() ultimately “only” raises an exception, it will only exit
the process when called from the main thread, and the exception is not
intercepted.

Note that this is the 'nice' way to exit. @glyphtwistedmatrix below points out that if you want a 'hard exit', you can use os._exit(*errorcode*), though it's likely os-specific to some extent (it might not take an errorcode under windows, for example), and it definitely is less friendly since it doesn't let the interpreter do any cleanup before the process dies. On the other hand, it does kill the entire process, including all running threads, while sys.exit() (as it says in the docs) only exits if called from the main thread, with no other threads running.

蓝梦月影 2024-07-13 09:33:10

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

例子:

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

A simple way to terminate a Python script early is to use the built-in quit() function. There is no need to import any library, and it is efficient and simple.

Example:

#do stuff
if this == that:
  quit()
墨落画卷 2024-07-13 09:33:10

另一种方法是:

raise SystemExit

Another way is:

raise SystemExit
余厌 2024-07-13 09:33:10

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

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

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

You can also use simply exit().

Keep in mind that sys.exit(), exit(), quit(), and os._exit(0) kill the Python interpreter. Therefore, if it appears in a script called from another script by execfile(), it stops execution of both scripts.

See "Stop execution of a script called with execfile" to avoid this.

最单纯的乌龟 2024-07-13 09:33:10

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

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

While you should generally prefer sys.exit because it is more "friendly" to other code, all it actually does is raise an exception.

If you are sure that you need to exit a process immediately, and you might be inside of some exception handler which would catch SystemExit, there is another function - os._exit - which terminates immediately at the C level and does not perform any of the normal tear-down of the interpreter; for example, hooks registered with the "atexit" module are not executed.

对你而言 2024-07-13 09:33:10

我刚刚发现,在编写多线程应用程序时,引发 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()

I've just found out that when writing a multithreadded app, raise SystemExit and sys.exit() both kills only the running thread. On the other hand, os._exit() exits the whole process. This was discussed in "Why does sys.exit() not exit when called inside a thread in Python?".

The example below has 2 threads. Kenny and Cartman. Cartman is supposed to live forever, but Kenny is called recursively and should die after 3 seconds. (recursive calling is not the best way, but I had other reasons)

If we also want Cartman to die when Kenny dies, Kenny should go away with os._exit, otherwise, only Kenny will die and Cartman will live forever.

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()
小…红帽 2024-07-13 09:33:10
from sys import exit
exit()

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

from sys import exit
exit()

As a parameter you can pass an exit code, which will be returned to OS. Default is 0.

想你只要分分秒秒 2024-07-13 09:33:10

我完全是个新手,但肯定这更干净、更可控

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() 系统退出

Edit

重点是程序顺利和平地结束,而不是“我停止了!!!”

I'm a total novice but surely this is cleaner and more controlled

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

if __name__ == '__main__': 
    main()

...

Program terminated

than

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

...

Program terminated Traceback (most recent call last): File "Z:\Directory\testdieprogram.py", line 12, in
main() File "Z:\Directory\testdieprogram.py", line 8, in main
sys.exit() SystemExit

Edit

The point being that the program ends smoothly and peacefully, rather than "I'VE STOPPED !!!!"

梦太阳 2024-07-13 09:33:10

问题

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

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

  • 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__)}")

Problem

In my practice, there was even a case when it was necessary to kill an entire multiprocessor application from one of those processes.

The following functions work well if your application uses the only main process. But no one of the following functions didn't work in my case as the application had many other alive processes.

  • quit()
  • exit(0)
  • os._exit(0)
  • sys.exit(0)
  • os.kill(os.getppid(), 9) - where os.getppid() is the pid of parent process

The last one killed the main process and itself but the rest processes were still alive.

Solution

I had to kill it by external command and finally found the solution using 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__)}")
青春如此纠结 2024-07-13 09:33: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!")

In Python 3.5, I tried to incorporate similar code without use of modules (e.g. sys, Biopy) other than what's built-in to stop the script and print an error message to my users. Here's my example:

## 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

Later on, I found it is more succinct to just throw an error:

## My example revised:
if "ATG" in my_DNA: 
    ## <Do something & proceed...>
else: 
    raise ValueError("Start codon is missing! Check your DNA sequence!")
岁月蹉跎了容颜 2024-07-13 09:33:10

只需在代码末尾添加 quit() 即可关闭 python 脚本。

Just put at the end of your code quit() and that should close a python script.

无名指的心愿 2024-07-13 09:33:10

在 Python 3.9 中,您还可以使用:raise SystemExit("Because I said so")

In Python 3.9, you can also use: raise SystemExit("Because I said so").

北笙凉宸 2024-07-13 09:33:10

我的两分钱。

Python 3.8.1、Windows 10、64 位。

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

我有几个 nexted 循环。

首先,我声明一个布尔变量,我将其称为 immediateExit

因此,在程序代码的开头我写:

immediateExit = False

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

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

然后我进入外部循环的立即延续,并且在代码执行任何其他操作之前,我写道:

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

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

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

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

'CSV file corrupted 1.5.'

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

随着从所有循环中逐渐退出 sys.exit,我设法做到了。

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

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

My two cents.

Python 3.8.1, Windows 10, 64-bit.

sys.exit() does not work directly for me.

I have several nexted loops.

First I declare a boolean variable, which I call immediateExit.

So, in the beginning of the program code I write:

immediateExit = False

Then, starting from the most inner (nested) loop exception, I write:

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

Then I go into the immediate continuation of the outer loop, and before anything else being executed by the code, I write:

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

Depending on the complexity, sometimes the above statement needs to be repeated also in except sections, etc.

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

The custom message is for my personal debugging, as well, as the numbers are for the same purpose - to see where the script really exits.

'CSV file corrupted 1.5.'

In my particular case I am processing a CSV file, which I do not want the software to touch, if the software detects it is corrupted. Therefore for me it is very important to exit the whole Python script immediately after detecting the possible corruption.

And following the gradual sys.exit-ing from all the loops I manage to do it.

Full code: (some changes were needed because it is proprietory code for internal tasks):

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

晨与橙与城 2024-07-13 09:33:10

在 .py 文件中使用 exitquit
和 sys.exit 用于 exe 文件

use exit and quit in .py files
and sys.exit for exe files

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文