一日一技:为什么exit()无法退出程序?

简介: 一日一技:为什么exit()无法退出程序?

我们在Python交互环境的里面,可能会使用exit()来退出程序,例如:


1.png


有时候,当我们想让Python程序在遇到某些条件的时候退出,也可以使用exit(),如下图所示:


def run(options):
    if options == '1':
        print('执行逻辑1')
    elif options == '2':
        print('执行逻辑2')
    elif options == 'exit':
        print('退出程序!')
        exit()
    else:
        print('只能输入1,2或者exit')
while True:
    option = input('请输入选项:')
    run(option)


2.png

但有时候,你会发现exit()似乎出了一些问题。执行它以后,程序虽然确实也会结束,但是它会报错。例如下面这段代码:


def run(options):
    if options == '1':
        print('执行逻辑1')
    elif options == '2':
        print('执行逻辑2')
    elif options == 'exit':
        print('退出程序!')
        exit()
    else:
        print('只能输入1,2或者exit')
while True:
    option = input('请输入选项:')
    try:
        run(option)
    except:
        pass


运行效果如下图所示:

image.gif

3.png


还有一些时候,exit()甚至直接失效,例如:


def func(param):
    def wrap(args):
        try:
            print(args)
            exit()
        except:
            pass
    wrap(param)
for i in range(10):
    func(i)


运行效果如下图所示。


4.png

要解释这个问题,我们就要先来搞清楚,在Python里面,退出当前程序的几个命令:exit()quit()sys.exit()os._exit()有什么区别和联系。


实际上,exit()quit()sys.exit(),他们背后的原理都是一样的,都是在执行的时候,抛出一个异常raise SystemExit。所以,我们甚至可以直接在代码里面手动抛出这个异常来退出程序:


5.png


在正常情况下,无论你是执行这三个命令,还是手动抛出SystemExit异常,Python解释器都能检查到这个异常,然后清理当前进程占用的各个句柄和缓存buffer。


但问题在于,SystemExit是基于BaseException实现的一个异常,所以当你的代码里面使用try...except...的时候,你会捕获到这个异常。但是在except里面,你又直接pass了,所以就什么也做不到。于是程序就无法正常退出了。


如果你非要使用try ... except ...其实也很简单,你使用具体的某个异常,或者直接使用Exception。这样一来,由于SystemExit不是基于Exception的,所以就不会被捕获。捕获了Exception以后,代码运行效果如下图所示:


6.png


从图中可以看到,程序打印了第一个数字就正常退出了。


上面的问题解决了,可能还有人会问,这四个退出方法有什么区别呢?其实exit()quit()完全一样,就是方便有些人习惯用exit这个词,有些人习惯用quit()这个词。一般来说,当你在Python互换环境里面,可以使用这两个函数的任何一个来退出。

sys.exit()需要提前导入sys模块。所以一般在.py项目代码里面使用。因为可能有些系统的Python环境,没有exit()quit()函数,但肯定有sys模块。


而至于os._exit()这个函数,它可以立刻结束当前进程,不会清理句柄,也不会清理缓存buffer。就相当于kill -9 进程ID


请关注微信公众号【未闻Code】获取更多精彩文章。

目录
相关文章
|
9月前
QUIT
QUIT
42 0
|
9月前
|
Shell
Shell 中断与退出(continue、break、exit)
Shell 中断与退出(continue、break、exit)
152 0
|
缓存 Linux
exit() 函数和 _exit() 函数
exit() 函数和 _exit() 函数
103 0
exit() 函数和 _exit() 函数
|
存储 物联网 Linux
Pthread_exit 线程退出|学习笔记
快速学习 Pthread_exit 线程退出
185 0
|
C++
C++学习007-使用exit退出进程
使用exit可以实现退出当前进程。
186 0