在程序退出之前做某事

Rac*_*caR 80 python function exit

如何在程序退出之前执行某项功能或某些功能?我有一个将在后台持续运行的脚本,我需要它在退出之前将一些数据保存到文件中.有这样做的标准方法吗?

Bre*_*ode 134

看看atexit模块:

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

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

import atexit

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

atexit.register(exit_handler)
Run Code Online (Sandbox Code Playgroud)

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

  • @RacecaR,即使一个进程严重崩溃或被残酷杀死,你可以运行终止代码的唯一方法是**另一个**进程,称为"监视器"或"看门狗",其唯一的工作就是密切关注目标进程并在适当时运行终止代码.当然,这需要一个非常不同的架构,并有其局限性; 如果你需要这样的功能,最好在这个问题上打开一个不同的Q. (14认同)
  • 如果按Ctrl + C,将调用它.这只会引发KeyboardInterrupt异常. (6认同)
  • 如果你按Ctrl + C或Ctrl + \,有什么方法可以调用它吗? (4认同)
  • @RacecaR:的确如此; 杀死进程的目的是阻止它死亡.从文档:`注意当程序被信号杀死,检测到Python致命内部错误或调用os._exit()时,不会调用exit函数. (2认同)

Bri*_*ane 29

如果你想要总是运行一些东西,即使是错误,请使用try:finally:喜欢这个 -

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

if __name__=='__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

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

  • 由于杀死进程而在SIGTERM发生时不起作用. (11认同)

Kat*_*iel 15

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

try:
    ...
except KeyboardInterrupt:
    # clean up
    raise
Run Code Online (Sandbox Code Playgroud)

我提到这只是为了让你了解它; "正确"的方法是atexit上面提到的模块.


Gar*_*Dan 8

这是根据其他答案改编的版本。它应该可以正常退出、终止和 PyCharm 停止按钮(我可以确认的最后一个)(尚未完全测试)。

import signal
import atexit


def handle_exit(*args):
    try:
        ... do computation ...
    except BaseException as exception:
        ... handle the exception ...


atexit.register(handle_exit)
signal.signal(signal.SIGTERM, handle_exit)
signal.signal(signal.SIGINT, handle_exit)
Run Code Online (Sandbox Code Playgroud)