Reputation: 10654
These days I am learning Python's Exception handling features deeply. I encountered exception SystemExit
. While reading about this from official Python Docs I got question in mind that what exactly would have happen when I terminate Python script by pressing Ctrl+c?
lets take this sample code:
def func1(a,b):
print "func1: "+str(a/b)
#some more functions
def func2(a,b):
print "func2: "+str(a/b)
#some more functions
if __name__=="__main__":
import random
count=0
for i in range(1000000):
count=count+1
print "count: "+str(count)
try:
func1(random.randint(-2,3),random.randint(-2,3))
except KeyboardInterrupt:
raise
except:
print "error in func1"
try:
func2(random.randint(-2,3),random.randint(-2,3))
except KeyboardInterrupt:
raise
except:
print "error in func2"
print "\n"
In this sample code I am catching KeyboardInterrupt
so I can stop my script by pressing Ctrl+c. Should I catch SystemExit
too to make this code more mature? if yes then why? actually this question is source of my main question which appear on title. so don't consider that I am asking two different question in one post.
Upvotes: 4
Views: 218
Reputation: 32542
You usually not need to catch SystemExit
as it is what makes exit()
and sys.exit()
functions work:
sys.exit([arg])
Exit from Python. This is implemented by raising the
SystemExit
exception, so cleanup actions specified byfinally
clauses oftry
statements are honored, and it is possible to intercept the exit attempt at an outer level.
Example:
try:
exit()
except SystemExit:
print "caught"
Therefore, you usually don't want to catch all exceptions in the first place (by using an empty except:
clause). The best approach is generally to make your exception handlers as specific as possible. It otherwise makes debugging your application exceptionally hard, as it either hides errors entirely or at least makes it hard to diagnose the details.
Upvotes: 4
Reputation: 279415
If you're uncertain what exceptions the code you're calling throws to indicate errors then you should (in order of preference):
Exception
, not everything.Neither KeyboardInterrupt
nor SystemExit
is a subclass of Exception
, but all of the standard Python exceptions used to indicate errors are.
Upvotes: 1
Reputation: 91149
Your title says something different than the body of your question.
To the title:
What happens internally is that python captures the SIGINT
and raises a KeyboardInterrupt
exception from it.
To the text:
You don't want to do except:
.
Instead, you want
if __name__=="__main__":
try:
import random
count=0
for i in range(1000000):
count=count+1
print "count: "+str(count)
try:
func1(random.randint(-2,3),random.randint(-2,3))
except Exception, e:
print "error in func1", e # or something...
try:
func2(random.randint(-2,3),random.randint(-2,3))
except Exception, e:
print "error in func2", e # or something...
print "\n"
except Exception:
raise # any other "normal" exception.
except: # Here it is ok, as you handle most exceptions above.
pass
Most "normal" exception which should normally be handled derive from Exception
. Those which have an internal meaning and should normally not be caught (except on global level) don't derive from Exception
.
These are KeyboardInterrupt
, SystemExit
and GeneratorExit
.
Upvotes: 1
Reputation: 388383
The only exception your functions can raise is a ZeroDivisionError
, so you should only catch that one:
import random
if __name__ == "__main__":
for count in range(1000000):
print "count:", count
try:
func1(random.randint(-2, 3),random.randint(-2, 3))
except ZeroDivisionError:
print "error in func1"
try:
func2(random.randint(-2, 3),random.randint(-2, 3))
except ZeroDivisionError:
print "error in func2"
print "\n"
Upvotes: 1