Exceptions in Python

Errors detected during execution are called exceptions and are not unconditionally fatal. Learn more about exceptions in Python here.

Errors detected during execution are called exceptions and are not unconditionally fatal. Most exceptions are not handled by programs; it is possible to write programs that handle selected exceptions. There are specific features in Python to deal with exceptions and exception logic. Furthermore, exceptions have a rich type hierarchy, all inheriting from the BaseException type.

Catching Exceptions in Python

Use try…except: to catch exceptions. You should specify as precise an exception as you can:

try:
x = 5 / 0
except ZeroDivisionError as e:

e is the exception object

print("Got a divide by zero! The exception was:", e)
handle exceptional case x = 0
finally:
print "The END"

it runs no matter what execute.

The exception class that is specified – in this case, ZeroDivisionError – catches any exception that is of that class or of any subclass of that exception.

For example, ZeroDivisionError is a subclass of ArithmeticError:

ZeroDivisionError.bases (,)

And so, the following will still catch the ZeroDivisionError:

try:
5 / 0
except ArithmeticError:
print("Got arithmetic error")

Do not catch everything!

While it’s often tempting to catch every Exception:

try:
very_difficult_function()
except Exception:
log / try to reconnect / exit gratiously finally:
print "The END"

it runs no matter what execute.

Or even everything (that includes BaseException and all its children including Exception):

try:
even_more_difficult_function()
except:
pass # do whatever needed

In most cases it’s bad practice. It might catch more than intended, such as SystemExit, KeyboardInterrupt and MemoryError – each of which should generally be handled differently than usual system or logic errors. It also means there’s no clear understanding for what the internal code may do wrong and how to recover properly from that condition. If you’re catching every error, you won’t know what error occurred or how to fix it.

This is more commonly referred to as ‘bug masking’ and should be avoided. Let your program crash instead of silently failing or even worse, failing at deeper level of execution. (Imagine it’s a transactional system)

Usually these constructs are used at the very outer level of the program, and will log the details of the error so that the bug can be fixed, or the error can be handled more specifically.

Re-raising exceptions

Sometimes you want to catch an exception just to inspect it, e.g. for logging purposes. After the inspection, you want the exception to continue propagating as it did before.

In this case, simply use the raise statement with no parameters.

try:
5 / 0
except ZeroDivisionError:
print("Got an error")
raise

Keep in mind, though, that someone further up in the caller stack can still catch the exception and handle it somehow. The done output could be a nuisance in this case because it will happen in any case (caught or not caught). So it might be a better idea to raise a different exception, containing your comment about the situation as well as the original exception:

try:
5 / 0
except ZeroDivisionError as e:
raise ZeroDivisionError("Got an error", e)

But this has the drawback of reducing the exception trace to exactly this raise while the raise without argument retains the original exception trace.

In Python 3 you can keep the original stack by using the raise-from syntax:

raise ZeroDivisionError("Got an error") from e

Catching multiple exceptions

There are a few ways to catch multiple exceptions.

The first is by creating a tuple of the exception types you wish to catch and handle in the same manner. This example will cause the code to ignore KeyError and AttributeError exceptions.

try:
d = {}
a = d[1]
b = d.non_existing_field
except (KeyError, AttributeError) as e:
print("A KeyError or an AttributeError exception has been caught.")

If you wish to handle different exceptions in different ways, you can provide a separate exception block for each type. In this example, we still catch the KeyError and AttributeError, but handle the exceptions in different manners.

try:
d = {}
a = d[1]
b = d.non_existing_field
except KeyError as e:
print("A KeyError has occurred. Exception message:", e)
except AttributeError as e:
print("An AttributeError has occurred. Exception message:", e)

exceptions in Python Hierarchy

Exception handling occurs based on an exception hierarchy, determined by the inheritance structure of the exception classes.

For example, IOError and OSError are both subclasses of EnvironmentError. Code that catches an IOError will not catch an OSError. However, code that catches an EnvironmentError will catch both IOErrors and OSErrors.

The hierarchy of built-in exceptions:

Python 2.x Version ≥ 2.3

BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StandardError
| +-- BufferError
| +-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- EnvironmentError
| +-- IOError
| +-- OSError
| +-- WindowsError (Windows)
| +-- VMSError (VMS)
+-- EOFError
+-- ImportError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError

GoalKicker.com – Python® Notes for Professionals 425

| +-- UnicodeError
+-- UnicodeDecodeError
+-- UnicodeEncodeError
+-- UnicodeTranslateError +-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning +-- RuntimeWarning
+-- SyntaxWarning +-- UserWarning +-- FutureWarning +-- ImportWarning +-- UnicodeWarning +-- BytesWarning

Python 3.x Version ≥ 3.0

BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
+-- FloatingPointError
+-- OverflowError
+-- ZeroDivisionError +-- AssertionError
+-- AttributeError +-- BufferError +-- EOFError
+-- ImportError +-- LookupError
+-- IndexError
+-- KeyError +-- MemoryError +-- NameError
+-- UnboundLocalError +-- OSError
+-- BlockingIOError
+-- ChildProcessError
+-- ConnectionError
| +-- BrokenPipeError
| +-- ConnectionAbortedError
| +-- ConnectionRefusedError
| +-- ConnectionResetError
+-- FileExistsError
+-- FileNotFoundError
+-- InterruptedError
+-- IsADirectoryError
+-- NotADirectoryError
+-- PermissionError
+-- ProcessLookupError
+-- TimeoutError +-- ReferenceError +-- RuntimeError
+-- NotImplementedError
+-- RecursionError +-- SyntaxError
+-- IndentationError
+-- TabError +-- SystemError +-- TypeError

GoalKicker.com – Python® Notes for Professionals 426

+-- ValueError
| +-- UnicodeError
+-- UnicodeDecodeError
+-- UnicodeEncodeError
+-- UnicodeTranslateError +-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning +-- RuntimeWarning
+-- SyntaxWarning +-- UserWarning +-- FutureWarning +-- ImportWarning +-- UnicodeWarning +-- BytesWarning +-- ResourceWarning

Else

Code in an else block will only be run if no exceptions were raised by the code in the try block. This is useful if you have some code you don’t want to run if an exception is thrown, but you don’t want exceptions thrown by that code to be caught.

For example:

try:
data = {1: 'one', 2: 'two'}
print(data[1])
except KeyError as e:
print('key not found')
else:
raise ValueError()
Output: one
Output: ValueError

Note that this kind of else: cannot be combined with an if starting the else-clause to an elif. If you have a

following if it needs to stay indented below that else::

try:

except …:

else:
if …:

elif …:

else:

Raising Exceptions

If your code encounters a condition it doesn’t know how to handle, such as an incorrect parameter, it should raise the appropriate exception.

def even_the_odds(odds):
if odds % 2 != 1:
raise ValueError("Did not get an odd number")

return odds + 1

Creating custom exceptions in Python types

Create a class inheriting from Exception:

class FooException(Exception):
pass
try:
raise FooException("insert description here")
except FooException:
print("A FooException was raised.")
or another exception type:
class NegativeError(ValueError):
pass
def foo(x):
function that only accepts positive values of x if x < 0:
raise NegativeError("Cannot process negative numbers")
… # rest of function body
try:
result = foo(int(input("Enter a positive integer: "))) # raw_input in Python 2.x except NegativeError:
print("You entered a negative number!")
else:
print("The result was " + str(result))

Practical examples of exception handling

User input

Imagine you want a user to enter a number via input. You want to ensure that the input is a number. You can use try/except for this:

Python 3.x Version ≥ 3.0

while True:
try:
nb = int(input('Enter a number: '))
break
except ValueError:
print('This is not a number, try again.')

Note: Python 2.x would use raw_input instead; the function input exists in Python 2.x but has different semantics.

In the above example, input would also accept expressions such as 2 + 2 which evaluate to a number.

If the input could not be converted to an integer, a ValueError is raised. You can catch it with except. If no exception is raised, break jumps out of the loop. After the loop, nb contains an integer.

Dictionaries

Imagine you are iterating over a list of consecutive integers, like range(n), and you have a list of dictionaries d that contains information about things to do when you encounter some particular integers, say skip the d[i] next ones.

d = [{7: 3}, {25: 9}, {38: 5}]
for i in range(len(d)):
do_stuff(i)
try:
dic = d[i]
i += dic[i]
except KeyError:
i += 1

A KeyError will be raised when you try to get a value from a dictionary for a key that doesn’t exist.

exceptions in Python are Objects too

Exceptions are just regular Python objects that inherit from the built-in BaseException. A Python script can use the raise statement to interrupt execution, causing Python to print a stack trace of the call stack at that point and a representation of the exception instance. For example:

def failing_function():
… raise ValueError('Example error!')
failing_function()
Traceback (most recent call last):
File "", line 1, in
File "", line 2, in failing_function
ValueError: Example error!

which says that a ValueError with the message ‘Example error!’ was raised by our failing_function(), which was executed in the interpreter.

Calling code can choose to handle any and all types of exception that a call can raise:

try:
… failing_function()
… except ValueError:
… print('Handled the error')
Handled the error

You can get hold of the exception objects by assigning them in the except… part of the exception handling code:

try:
… failing_function()
… except ValueError as e:
… print('Caught exception', repr(e))
Caught exception ValueError('Example error!',)

A complete list of built-in Python exceptions along with their descriptions can be found in the Python Documentation: https://docs.python.org/3.5/library/exceptions.html. And here is the full list arranged hierarchically: Exception Hierarchy.

Running clean-up code with finally

Sometimes, you may want something to occur regardless of whatever exception happened, for example, if you have to clean up some resources.

The finally block of a try clause will happen regardless of whether any exceptions were raised.

resource = allocate_some_expensive_resource()
try:
do_stuff(resource)
except SomeException as e:
log_error(e)
raise # re-raise the error
finally:
free_expensive_resource(resource)

This pattern is often better handled with context managers (using the with statement).

Chain exceptions in Python with raise from

In the process of handling an exception, you may want to raise another exception. For example, if you get an IOError while reading from a file, you may want to raise an application-specific error to present to the users of your library, instead.

Python 3.x Version ≥ 3.0

You can chain exceptions to show how the handling of exceptions proceeded:

try: 5 / 0
except ZeroDivisionError as e:
raise ValueError("Division failed") from e
Traceback (most recent call last):
File "", line 2, in
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "", line 4, in
ValueError: Division failed

Must Read Python Interview Questions

200+ Python Tutorials With Coding Examples

Python Language Basics TutorialPython String Representations of Class Instances
Python For Beginners TutorialPython Debugging Tutorial
Python Data Types TutorialReading and Writing CSV File Using Python
Python Indentation TutorialWriting to CSV in Python from String/List
Python Comments and Documentation TutorialPython Dynamic Code Execution Tutorial
Python Date And Time TutorialPython Code Distributing using Pyinstaller
Python Date Formatting TutorialPython Data Visualization Tutorial
Python Enum TutorialPython Interpreter Tutorial
Python Set TutorialPython Args and Kwargs
Python Mathematical Operators TutorialPython Garbage Collection Tutorial
Python Bitwise Operators TutorialPython Pickle Data Serialisation
Python Bolean Operators TutorialPython Binary Data Tutorial
Python Operator Precedance TutorialPython Idioms Tutorial
Python Variable Scope And Binding TutorialPython Data Serialization Tutorial
Python Conditionals TutorialPython Multiprocessing Tutorial
Python Comparisons TutorialPython Multithreading Tutorial
Python Loops TutorialPython Processes and Threads
Python Arrays TutorialPython Concurrency Tutorial
Python Multidimensional Arrays TutorialPython Parallel Computation Tutorial
Python List TutorialPython Sockets Module Tutorial
Python List Comprehensions TutorialPython Websockets Tutorial
Python List Slicing TutorialSockets Encryption Decryption in Python
Python Grouby() TutorialPython Networking Tutorial
Python Linked Lists TutorialPython http Server Tutorial
Linked List Node TutorialPython Flask Tutorial
Python Filter TutorialIntroduction to Rabbitmq using Amqpstorm Python
Python Heapq TutorialPython Descriptor Tutorial
Python Tuple TutorialPython Tempflile Tutorial
Python Basic Input And Output TutorialInput Subset and Output External Data Files using Pandas in Python
Python Files And Folders I/O TutorialUnzipping Files in Python Tutorial
Python os.path TutorialWorking with Zip Archives in Python
Python Iterables And Iterators Tutorialgzip in Python Tutorial
Python Functions TutorialStack in Python Tutorial
Defining Functions With List Arguments In PythonWorking with Global Interpreter Lock (GIL)
Functional Programming In PythonPython Deployment Tutorial
Partial Functions In PythonPython Logging Tutorial
Decorators Function In PythonPython Server Sent Events Tutorial
Python Classes TutorialPython Web Server Gateway Interface (WSGI)
Python Metaclasses TutorialPython Alternatives to Switch Statement
Python String Formatting TutorialPython Packing and Unpacking Tutorial
Python String Methods TutorialAccessing Python Sourcecode and Bytecode
Using Loops Within Functions In PythonPython Mixins Tutorial
Python Importing Modules TutorialPython Attribute Access Tutorial
Difference Betweeb Module And Package In PythonPython Arcpy Tutorial
Python Math Module TutorialPython Abstract Base Class Tutorial
Python Complex Math TutorialPython Plugin and Extension Classes
Python Collections Module TutorialPython Immutable Datatypes Tutorial
Python Operator Module TutorialPython Incompatibilities Moving from Python 2 to Python 3
Python JSON Module TutorialPython 2to3 Tool Tutorial
Python Sqlite3 Module TutorialNon-Official Python implementations
Python os Module TutorialPython Abstract Syntax Tree
Python Locale Module TutorialPython Unicode and Bytes
Python Itertools Module TutorialPython Serial Communication (pyserial)
Python Asyncio Module TutorialNeo4j and Cypher using Py2Neo
Python Random Module TutorialBasic Curses with Python
Python Functools Module TutorialTemplates in Python
Python dis Module TutorialPython Pillow
Python Base64 Module TutorialPython CLI subcommands with precise help output
Python Queue Module TutorialPython Database Access
Python Deque Module TutorialConnecting Python to SQL Server
Python Webbrowser Module TutorialPython and Excel
Python tkinter TutorialPython Turtle Graphics
Python pyautogui Module TutorialPython Persistence
Python Indexing And Slicing TutorialPython Design Patterns
Python Plotting With Matplotlib TutorialPython hashlib
Python Graph Tool TutorialCreating a Windows Service Using Python
Python Generators TutorialMutable vs Immutable (and Hashable) in Python
Python Reduce TutorialPython configparser
Python Map Function TutorialPython Optical Character Recognition
Python Exponentiation TutorialPython Virtual Environments
Python Searching TutorialPython Virtual Environment – virtualenv
Sorting Minimum And Maximum In PythonPython Virtual environment with virtualenvwrapper
Python Print Function TutorialCreate virtual environment with virtualenvwrapper in windows
Python Regular Expressions Regex TutorialPython sys Tutorial
Copying Data In Python TutorialChemPy – Python package
Python Context Managers (“with” Statement) TutorialPython pygame
Python Name Special Variable TutorialPython pyglet
Checking Path Existence And Permissions In PythonWorking with Audio in Python
Creating Python Packages TutorialPython pyaudio
Usage of pip Module In Python TutorialPython shelve
Python PyPi Package Manager TutorialIoT Programming with Python and Raspberry PI
Parsing Command Line Arguments In Pythonkivy – Cross-platform Python Framework for NUI Development
Python Subprocess Library TutorialPandas Transform
Python setup.py TutorialPython vs. JavaScript
Python Recursion TutorialCall Python from C#
Python Type Hints TutorialPython Writing Extensions
Python Exceptions TutorialPython Lex-Yacc
Raise Custom Exceptions In PythonPython Unit Testing
Python Commonwealth Exceptions TutorialPython py.test
Python urllib TutorialPython Profiling
Web Scraping With Python TutorialPython Speed of Program
Python HTML Parsing TutorialPython Performance Optimization
Manipulating XML In PythonPython Security and Cryptography
Python Requests Post TutorialSecure Shell Connection in Python
Python Distribution TutorialPython Anti Patterns
Python Property Objects TutorialPython Common Pitfalls
Python Overloading TutorialPython Hidden Features
Python Polymorphism TutorialPython For Machine Learning
Python Method Overriding TutorialPython Interview Questions And Answers For Experienced
Python User Defined Methods TutorialPython Coding Interview Questions And Answers
Python Programming Tutorials With Examples

Other Python Tutorials

Leave a Comment