Reputation: 3802
What is the best way to properly finalize python script when sys.exit() is called?
For example I have an app which: - opened log file - opened some USB gadget - decide it's time to close the app - call sys.exit(-1) - (or alternatively it throw harsh exception - but I prefer first way as I was little piggy and some parts of code actually catch all exceptions, which would stop my termination exception...)
Then I would need some finalize() function which would be certainly called before exiting the interpreter. Finalize() would free USB gadget and close log file in exactly this order.
I tried def del but it is not called upon sys.exit and furthermore I can not decide in which order _del_s would be called.
Is there some salvation for me? Or do I have to do: 1. Top most try-catch-finally 2. Do the exit with some specific Exception 3. everywhere on each exception catch specify exactly what I'm catching?
Upvotes: 1
Views: 801
Reputation: 3802
Ok I found the answer which suites me best:
import sys
try:
print "any code: allocate files, usb gadets etc "
try:
sys.exit(-1) # some severe error occure
except Exception as e:
print "sys.exit is not catched:"+str(e)
finally:
print "but all sub finallies are done"
print "shall not be executed when sys.exit called before"
finally:
print "Here we can properly free all resources in our preferable order"
print "(ie close log file at the end after closing all gadgets)"
as for recommended solution atexit - it would be nice and all but it does not work in my python 2.6. I tried this:
import sys
import atexit
def myFinal():
print "it doesn't print anything in my python 2.6 :("
atexit.register(myFinal)
print "any code"
sys.exit(-1) # is it pluged in?
print "any code - shall not be execute"
As for Wrapper solution - it's definitely most fancy - but honestly I can not say how it's better...
import sys
class mainCleanupWrapper(object):
def __enter__(self):
print "preallocate resources optionally"
def __exit__(self, type, value, traceback):
print "I release all resources in my order"
with mainCleanupWrapper() as whatsThisNameFor:
print "ok my unchaged code with any resources locking"
sys.exit(-1)
print "this code shall not be executed"
I found my solution - but frankly python seems to be getting pretty bulky and bloated...
Upvotes: 0
Reputation: 8307
See python's with
statement.
class UsbWrapper(object):
def __enter__(self):
#do something like accessing usb_gadget (& acquire lock on it)
#usb_gadget_handle = open_usb_gadget("/dev/sdc")
#return usb_gadget_handle
def __exit__(self, type, value, traceback):
#exception handling goes here
#free the USB(lock) here
with UsbWrapper() as usb_device_handle:
usb_device_handle.write(data_to_write)
No matter whether the code throws exception or runs as desired, the USB lock is always released.
Upvotes: 1