暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

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

未闻Code 2021-09-22
1202

 

摄影:产品经理

产品经理又出去喝酒了

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

有时候,当我们想让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)

但有时候,你会发现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

运行效果如下图所示:

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

def func(param):
    def wrap(args):
        try:
            print(args)
            exit()
        except:
            pass
    wrap(param)

for i in range(10):
    func(i)

运行效果如下图所示。

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

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

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

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

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

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

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

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

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

END

未闻 Code·知识星球开放啦!

一对一答疑爬虫相关问题

职业生涯咨询

面试经验分享

每周直播分享

......

未闻 Code·知识星球期待与你相见~

一二线大厂在职员工

十多年码龄的编程老鸟

国内外高校在读学生

中小学刚刚入门的新人

“未闻 Code技术交流群”等你来!

入群方式:添“mekingname”,备注“粉丝群”(谢绝广告党,非诚勿扰!)

文章转载自未闻Code,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论