In Python programs we deal with problems with files, modules and incorrect logic. For some kinds of errors, we must always be prepared.
We use special keywords in Python programs to handle errors. These keywords include the try, except and raise keywords.
Here we introduce a block that follows the try statement. The division expression has zero as the denominator, causing a ZeroDivisionError
.
ZeroDivisionError
. And we print a special message.try: x = 1 / 0 except ZeroDivisionError: print("Tried to divide by zero")Tried to divide by zero
We create exceptions in our code with raise. This program uses the Exception
type. The mistake()
method creates a custom string
based on its parameter. It then raises an exception.
mistake()
call is shown.def mistake(name): # Raise an example with custom string. raise Exception(name + " caused exception") # Call method. mistake("Voorheesville")Traceback (most recent call last): File "C:\file.py", line 4, in <module> mistake("Voorheesville") File "C:\file.py", line 2, in mistake raise Exception(name + " caused exception") Exception: Voorheesville caused exception
An exception continues bubbling to the calling methods unless handled. In an except clause, we can use a "raise" statement with no argument. This reraises the exception.
try: # This causes an exception. f = open("abc") except: print("Except hit") # Raise the exception again. raiseExcept hit Traceback (most recent call last): File "C:\programs\file.py", line 6, in <module> f = open("abc") IOError: [Errno 2] No such file or directory: 'abc'
The else
-statement can be used after a try-except
block. If no exception is thrown, the else
-statements are executed. The else must come after the excepts.
while-True
infinite loop. We accept input from the console, and parse it with the int()
built-in method.while True: # Read int from console. denominator = int(input()) # Use int as denominator. try: i = 1 / denominator except: print("Error") else: print("OK")1 OK 2 OK 0 Error
This clause is always executed, even if an error is raised. We can use "finally" statements as a way to clean up, or ensure completion of tasks.
try: # An error occurs. x = 1 / 0 except: # Except clause: print("Error encountered") finally: # Finally clause: print("Finally clause reached")Error encountered Finally clause reached
As
-keywordWe can name a variable within an except statement. We use the as
-keyword for this. Here we name the IOError
"err" and can use it within the clause.
try: f = open("does-not-exist") except IOError as err: # We can use IOError as an instance. print("Error:", err) print("Number:", err.errno)Error: [Errno 2] No such file or directory: 'does-not-exist' Number: 2
When a program crashes, a stack trace (a list of the calling methods) is helpful for debugging. In Python this is called a Traceback. It is a call stack.
ZeroDivisionError
. We see the inner()
method too in the Traceback.def outer(n): return 100 / n def inner(n): return outer(n) # This causes an error. # ... Python provides a stack trace that shows the call stack. inner(0)Traceback (most recent call last): File "C:\programs\file.py", line 12, in <module> inner(0) File "C:\programs\file.py", line 8, in inner return outer(n) File "C:\programs\file.py", line 5, in outer return 100 / n ZeroDivisionError: division by zero
We can benchmark small programs to determine the speed of constructs. Here we examine the performance of raising exceptions.
ZeroDivisionError
on each iteration.if
-statement, and no exception is raised.import time print(time.time()) # Version 1: cause exception. v = 0 i = 0 while i < 10000000: try: x = 10 / v except ZeroDivisionError: x = 0 i += 1 print(time.time()) # Version 2: use if-check. v = 0 i = 0 while i < 10000000: if v != 0: x = 10 / v else: x = 0 i += 1 print(time.time())1346178493.989 1346178499.7 (Version 1 = 5.711 s) 1346178501.788 (Version 2 = 2.088 s)
With assert()
we cause an AssertionError
when a condition is not true. So we "assert" that conditions are valid as the program runs. These statements can be optimized out.
Many specific errors occur in Python programs. Even aspects of a program such as its indentation leads to errors. Other problems, such as invalid method calls, also provoke trouble.
Exceptions provide a cleaner, simpler way to handle certain types of errors. They streamline programs. They eliminate the burden of excessive error checks in important logic.