【问题标题】:Doing something before program exit在程序退出之前做某事
【发布时间】:2011-04-20 11:58:59
【问题描述】:

你怎么能有一个函数或东西在你的程序退出之前被执行?我有一个将在后台持续运行的脚本,我需要它在退出之前将一些数据保存到文件中。有这样做的标准方法吗?

【问题讨论】:

  • 脚本不应该停止,但也许有人会终止进程或按 Ctrl+\ 或其他东西。

标签: python function exit


【解决方案1】:

查看atexit 模块:

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

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

import atexit

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

atexit.register(exit_handler)

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

【讨论】:

  • 如果你按下 Ctrl+C 或 Ctrl+\,有什么方法可以让它被调用?
  • 按Ctrl+C会调用。这只会引发 KeyboardInterrupt 异常。
  • 哦,我忘了。而且我假设如果有人杀死了 python 进程,你能做的任何事情都不会运行?
  • @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.
  • @RacecaR,即使进程严重崩溃或被残忍地杀死,您可以运行终止代码的唯一方法是在 另一个 进程中,称为“监视器”或“看门狗” ",其唯一的工作是密切关注目标进程并在适当的时候运行终止代码。当然,这需要一个非常不同的架构并且有其局限性;如果你需要这样的功能,你最好打开一个关于这个问题的不同 Q。
【解决方案2】:

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

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

if __name__=='__main__':
    main()

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

【讨论】:

  • 由于进程被杀死而发生SIGTERM时不起作用。
【解决方案3】:

如果您通过引发 KeyboardInterrupt(例如,通过按 Ctrl-C)来停止脚本,您可以将其作为标准异常捕获。同样的方法也可以抓到SystemExit

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

我提这个只是为了让你知道;执行此操作的“正确”方法是上面提到的 atexit 模块。

【讨论】:

    【解决方案4】:

    如果您有在程序的整个生命周期中存在的类对象,您还可以使用 __del__(self) 方法从类中执行命令:

    class x:
    def __init__(self):
        while True:
            print ("running")
            sleep(1)
    
    def __del__(self):
        print("destructuring")
    
    
    a = x()
    

    如果执行被中止,这也适用于正常程序结束,肯定会有一些例外:

    running
    running
    running
    running
    running
    Traceback (most recent call last):
      File "x.py", line 14, in <module>
        a = x()
      File "x.py", line 8, in __init__
        sleep(1)
    KeyboardInterrupt
    destructuring
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多