程序退出前做些事情


100

在程序退出之前,如何拥有要执行的功能或某些东西?我有一个脚本会在后台不断运行,并且我需要它在退出之前将一些数据保存到文件中。有这样做的标准方法吗?


2
该脚本永远都不应停止,但是也许有人会杀死该进程或按Ctrl + \或其他命令。
RacecaR 2010年

Answers:


165

检出atexit模块:

http://docs.python.org/library/atexit.html

例如,如果我想在应用程序终止时打印一条消息:

import atexit

def exit_handler():
    print 'My application is ending!'

atexit.register(exit_handler)

请注意,这对于正常终止脚本非常有用,但是在所有情况下都不会调用它(例如致命的内部错误)。


5
如果按Ctrl + C或Ctrl + \,有什么方法可以使其在要调用的位置进行?
RacecaR 2010年

8
如果您按Ctrl + C,它将被调用。那只是引发了KeyboardInterrupt异常。
Ned Batchelder

1
哦,我忘了。而且我认为,如果有人杀死python进程,您将无法执行任何操作,对吗?
RacecaR 2010年

5
@RacecaR:确实;终止进程的目的是使进程停止运行。从文档中:Note The exit function is not called when the program is killed by a signal, when a Python fatal internal error is detected, or when os._exit() is called
卡特里尔(Katriel)2010年

18
@RacecaR,即使一个进程严重崩溃或被残酷地杀死,您也可以运行终止代码的唯一方法是在另一个进程中,进程被称为“监视器”或“看门狗”,其唯一的工作就是关注目标进程,并且适当时运行终止代码。当然,这需要非常不同的体系结构并有其局限性。如果您需要这样的功能,则最好为此开一个不同的问号。
Alex Martelli

32

如果您希望某些东西始终运行,即使出现错误,也可以try: finally:这样使用-

def main():
    try:
        execute_app()
    finally:
        handle_cleanup()

if __name__=='__main__':
    main()

如果您还想处理异常,可以在except:之前插入finally:


13
当由于终止进程而发生SIGTERM时,此命令不起作用。
2015年

16

如果通过引发KeyboardInterrupt(例如,按Ctrl-C)停止脚本,则可以将其作为标准异常捕获。您也可以SystemExit用相同的方式捕捉。

try:
    ...
except KeyboardInterrupt:
    # clean up
    raise

我提到这一点只是为了让您知道。做到这一点的“正确”方法是上述atexit模块。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.