85419

Performing an action upon unexpected exit python

Question:

I was wandering if there was a way to perform an action before the program closes. I am running a program over a long time and I do want to be able to close it and have the data be saved in a text file or something but there is no way of me interfering with the while True loop I have running, and simply saving the data each loop would be highly ineffective.

So is there a way that I can save data, say a list, when I hit the x or destroy the program? I have been looking at the atexit module but have had no luck, except when I set the program to finish at a certain point.

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

That is my whole atexit part of the code and like I said, it runs fine when I set it to close through the while loop.

Is this possible, to save something when the application is terminated?

Answer1:

Your atexit usage is wrong. It expects a function and its arguments, but you're just calling your function right away and passing the result to atexit.register(). Try:

atexit.register(saveFile, list)

Be aware that this uses the list reference as it exists at the time you call atexit.register(), so if you assign to list afterwards, those changes will not be picked up. Modifying the list itself without reassigning should be fine, though.

Answer2:

You could use the handle_exit context manager from this ActiveState recipe:

<a href="http://code.activestate.com/recipes/577997-handle-exit-context-manager/" rel="nofollow">http://code.activestate.com/recipes/577997-handle-exit-context-manager/</a>

It handles SystemExit, KeyboardInterrupt, SIGINT, and SIGTERM, with a simple interface:

def cleanup(): print 'do some cleanup here' def main(): print 'do something' if __name__ == '__main__': with handle_exit(cleanup): main()

There's nothing you can in reaction to a SIGKILL. It kills your process immediately, without any allowed cleanup.

Answer3:

Catch the SystemExit exception at the top of your application, then rethrow it.

Answer4:

There are a a couple of approaches to this. As some have commented you could used signal handling ... your <strong>[Ctrl]+[C]</strong> from the terminal where this is running in the foreground is dispatching a <strong><em>SIGHUP</em></strong> signal to your process (from the terminal's drivers).

Another approach would be to use a non-blocking os.read() on <em>sys.stdin.fileno</em> such that you're polling your keyboard one during every loop to see if an "exit" keystroke or sequence has been entered.

A similarly non-blocking polling approach can be implemented using the <em>select</em> module's functionality. I've see that used with the <em>termios</em> and <em>tty</em> modules. (Seems inelegant that it needs all those to save, set changes to, and restore the terminal settings, and I've also seen some examples using <em>os</em> and <em>fcntl</em>; and I'm not sure when or why one would prefer one over the other if os.isatty(sys.stdin.fileno())).

Yet another approach would be to use the <strong>curses</strong> module with window.nodelay() or window.timeout() to set your desired input behavior and then either window.getch() or window.getkey() to poll for any input.

Recommend

  • undefined method `posts_path' for #
  • wchar_t is 2-bytes in visual studio and stores UTF-16. How do Unicode-aware applications work with c
  • Web Application and In-Memory State
  • Using replacements with a raw Sequelize query: avoiding single quotes?
  • FParsec: how to combine parsers so that they will be matched in arbitrary order
  • Determine if UTF-8 encoded NSData contains a null-terminated string
  • PhpStorm: annotation for inherited method return type?
  • Update varbinary(MAX) field in SQLServer 2012 Lost Last 4 bits
  • Pythons argparse default value doesn't work
  • How dotnet build chooses the output name
  • Detection of framework usage on Mac system?
  • What causes the runtime difference in this trivial fortran code?
  • Is there a package like bigmemory in R that can deal with large list objects?
  • netsh acl setting (need alternative method - registry settings?)
  • hide missing dates from x-axis ggplot2
  • Memory error in python- how to use more memory
  • ViewController With Transparent Background Entering Current ViewController With Push Transition
  • Sort List of Strings By Version
  • Jackson Parser: ignore deserializing for type mismatch
  • Meteor: Do Something On Email Verification Confirmation
  • Illegal mix of collations for operation for date/time comparison
  • C# - Is there a limit to the size of an httpWebRequest stream?
  • Is my CUDA kernel really runs on device or is being mistekenly executed by host in emulation?
  • C# - Serializing and deserializing static member
  • Sony Xperia Z Tablet not found by adb
  • How to recover from a Spring Social ExpiredAuthorizationException
  • Sending data from AppleScript to FileMaker records
  • MySQL WHERE-condition in procedure ignored
  • Perl system calls when running as another user using sudo
  • Where to put my custom functions in Wordpress?
  • How can I estimate amount of memory left with calling System.gc()?
  • RestKit - RKRequestDelegate does not exist
  • How to include full .NET prerequisite for Wix Burn installer
  • WPF Applying a trigger on binding failure
  • Hits per day in Google Big Query
  • Is it possible to post an object from jquery to bottle.py?
  • Binding checkboxes to object values in AngularJs
  • Net Present Value in Excel for Grouped Recurring CF
  • jQuery Masonry / Isotope and fluid images: Momentary overlap on window resize
  • How to load view controller without button in storyboard?