How can you have a function or something that will be executed before your program quits? I have a script that will be constantly running in the background, and I need it to save some data to a file before it exits. Is there a standard way of doing this?
+10
A:
Check out the atexit
module:
http://docs.python.org/library/atexit.html
For example, if I wanted to print a message when my application was terminating:
import atexit
def exit_handler():
print 'My application is ending!'
atexit.register(exit_handler)
Just be aware that this works great for normal termination of the script, but it won't get called in all cases (e.g. fatal internal errors).
Brent Nash
2010-10-03 15:04:35
Is there any way to make it where it will be called if you press Ctrl+C or Ctrl+\?
RacecaR
2010-10-03 15:08:39
It will be called if you press Ctrl+C. That simply raises a KeyboardInterrupt exception.
Ned Batchelder
2010-10-03 15:11:03
Oh, I forgot that. And I assume that nothing you can do will be run if somebody kills the python process right?
RacecaR
2010-10-03 15:11:41
@RacecaR: indeed; the point of killing a process is to stop it dead. From the docs: `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`.
katrielalex
2010-10-03 15:12:33
@RacecaR, the only way you can run termination code even if a process badly crashes or is brutally killed is in **another** process, known as a "monitor" or "watchdog", whose only job is to keep an eye on the target process and run the termination code when apropriate. Of course that requires a very different architecture and has its limitations; if you need such functionality it's best for you to open a different Q on the matter.
Alex Martelli
2010-10-03 15:18:20
But you can listen to signals, see the signal module.
THC4k
2010-10-03 15:20:40
@Alex Martelli: your comment deserves to be a separate answer
bgbg
2010-10-03 15:42:37
+1
A:
If you stop the script by raising a KeyboardInterrupt
(e.g. by pressing Ctrl-C), you can catch that just as a standard exception. You can also catch SystemExit
in the same way.
try:
...
except KeyboardInterrupt:
# clean up
raise
I mention this just so that you know about it; the 'right' way to do this is the atexit
module mentioned above.
katrielalex
2010-10-03 15:11:04
A:
If you want something to always run, even on errors, use try: finally: like this -
def main():
try:
execute_app()
finally:
handle_cleanup()
if __name__=='__main__':
main()
If you want to also handle exceptions you can insert an except: before the finally:
Brian C. Lane
2010-10-03 16:38:47