【问题标题】:Performing an action upon unexpected exit python在意外退出python时执行操作
【发布时间】:2013-07-14 12:58:20
【问题描述】:

如果有办法在程序关闭之前执行某项操作,我正在徘徊。我正在运行一个程序很长时间,我确实希望能够关闭它并将数据保存在文本文件或其他东西中,但是我无法干扰我正在运行的while True 循环,并且简单地保存每个循环的数据将是非常无效的。

那么当我点击x 或销毁程序时,有没有办法可以保存数据,比如列表?我一直在查看 atexit 模块,但没有运气,除非我将程序设置为在某个时间点完成。

def saveFile(list):
    print "Saving List"
    with open("file.txt", "a") as test_file:
        test_file.write(str(list[-1]))

atexit.register(saveFile(list))

这是我整个atexit 代码的一部分,就像我说的,当我将它设置为通过while loop 关闭时它运行良好。

这样可以在应用程序终止时保存一些东西吗?

【问题讨论】:

  • 您应该注册一个 SIGINT 处理程序:stackoverflow.com/q/1112343/624900
  • 当一个程序被杀死时,它在死亡之前无法做任何事情。最好为定期终止提供一些用户界面
  • @MichaelButscher 取决于kill的类型,可以捕获SIGINT和SIGTERM,不能捕获SIGKILL
  • @jterrace 从问题的内容来看,我认为他的意思是 SIGKILL,但我应该说得更清楚

标签: python terminate


【解决方案1】:

您的atexit 用法错误。它需要一个函数及其参数,但您只是立即调用您的函数并将结果传递给atexit.register()。试试:

atexit.register(saveFile, list)

请注意,这使用了 list 引用,因为它在您调用 atexit.register() 时存在,因此如果您之后分配给 list,这些更改将不会被拾取。不过,修改列表本身而不重新分配应该没问题。

【讨论】:

  • 退出时不再调用该函数。该程序刚刚关闭。什么都没有发生。
  • 你是如何停止程序的?
  • 只需点击命令行窗口上的x 按钮。有没有其他方法可以在代码中做到这一点?
【解决方案2】:

您可以使用此 ActiveState 配方中的 handle_exit 上下文管理器:

http://code.activestate.com/recipes/577997-handle-exit-context-manager/

它处理SystemExitKeyboardInterruptSIGINTSIGTERM,界面简单:

def cleanup():
    print 'do some cleanup here'

def main():
    print 'do something'

if __name__ == '__main__':
    with handle_exit(cleanup):
        main()

您对SIGKILL 无能为力。它会立即终止您的进程,无需进行任何允许的清理。

【讨论】:

    【解决方案3】:

    在应用程序顶部捕获 SystemExit 异常,然后重新抛出它。

    【讨论】:

      【解决方案4】:

      有几种方法可以解决这个问题。正如一些人评论的那样,您可以使用信号处理...您的 [Ctrl]+[C] 来自在前台运行的终端正在调度 SIGHUP 向您的进程发出信号(来自终端的驱动程序)。

      另一种方法是在 sys.stdin.fileno 上使用非阻塞 os.read(),这样您就可以在每个循环期间轮询键盘,以查看“退出”击键或序列是否有已输入。

      使用 select 模块的功能可以实现类似的非阻塞轮询方法。我已经看到与 termiostty 模块一起使用。 (似乎不优雅,它需要所有这些来保存、设置更改和恢复终端设置,我还看到了一些使用 osfcntl 的示例>;如果os.isatty(sys.stdin.fileno()),我不确定何时或为什么会更喜欢其中一个。

      另一种方法是使用带有window.nodelay()window.timeout()curses 模块来设置您想要的输入行为,然后使用window.getch()window.getkey() 来轮询任何输入。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-22
        • 2017-03-27
        • 1970-01-01
        • 2012-08-29
        • 1970-01-01
        • 2017-04-05
        • 1970-01-01
        相关资源
        最近更新 更多