在意外的退出python上执行操作

时间:2013-07-13 17:55:55

标签: python terminate

如果在程序关闭之前有办法执行某个操作,我就会徘徊。我正在运行一个程序很长一段时间,我确实希望能够关闭它并将数据保存在文本文件或其他东西中,但是我无法干扰我运行的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关闭时,它运行正常。

是否可以在应用程序终止时保存某些内容?

4 个答案:

答案 0 :(得分:5)

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

atexit.register(saveFile, list)

请注意,这会使用您list时调用的atexit.register()引用,因此,如果您之后分配到list,则不会选择这些更改。但是,在不重新分配的情况下修改列表本身应该没问题。

答案 1 :(得分:4)

您可以使用此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没有任何反应。它立即杀死你的过程,没有任何允许的清理。

答案 2 :(得分:2)

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

答案 3 :(得分:0)

有两种方法可以解决这个问题。正如一些人评论过你可以使用信号处理......来自前台运行的终端的 [Ctrl] + [C] 正在调度 SIGHUP 向您的流程发出信号(来自终端的司机)。

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

使用 select 模块的功能可以实现类似的非阻塞轮询方法。我看到它与 termios tty 模块一起使用。 (似乎不太优雅,它需要所有保存,设置更改和恢复终端设置,我还看到一些使用 os {{1}的示例} ;如果fcntl),我不确定何时或为什么人会更喜欢一个而不是另一个。

另一种方法是使用 os.isatty(sys.stdin.fileno()) 模块与curseswindow.nodelay()设置所需的输入行为,然后window.timeout()window.getch()轮询任何输入。