Exceptions

This section is about exceptions, that is, language functions that specifically handle unusual circumstances during the execution of a programme. The most common exception is to handle errors, but they can also be used effectively for many other purposes. Python provides a comprehensive set of exceptions, and you can define new exceptions for your own purposes.

The entire exception mechanism in Python is object-oriented: An exception is an object that is automatically created by Python functions with a raise statement. This raise statement causes the Python programme to be executed in a different way than usually intended: The current call chain is searched for a handler that can handle the generated exception. If such a handler is found, it is called and can access the exception object to obtain further information. If no suitable exception handler is found, the programme terminates with an error message.

It is possible to create different types of exceptions to reflect the actual cause of the reported error or unusual circumstance. For an overview of the class hierarchy of built-in exceptions, see Exception hierarchy in the Python documentation. Each exception type is a Python class that inherits from its parent exception type. For example, a ZeroDivisionError is also an ArithmeticError, an Exception and also a BaseException by inheritance. This hierarchy is intentional: most exceptions inherit from Exception, and it is strongly recommended that all user-defined exceptions also subclass Exception, and not BaseException:

class EmptyFileError(Exception):
    pass

This defines your own exception type, which inherits from the Exception base type.

filenames = ["myFile1.py", "nonExistent.py", "emptyFile.py", "myFile2.py"]

A list of different file types is defined.

Finally, exceptions or errors are caught and handled using the compound statement try-except-else-finally. Any exception that is not caught will cause the programme to terminate.

 7    try:
 8        f = open(file, "r")
 9        line = f.readline()
10        if line == "":
11            f.close()
12            raise EmptyFileError(f"{file} is empty")
13    except IOError as error:
14        print(f"Cannot open file {file}: {error.strerror}")
15    except EmptyFileError as error:
16        print(error)
17    else:
18        print(f"{file}: {f.readline()}")
19    finally:
20        print("File", file, "processed")
Line 7

If an IOError or EmptyFileError occurs during the execution of the instructions in the try block, the corresponding except block is executed.

Line 9

An IOError could be triggered here.

Line 12

Here you trigger the EmptyFileError.

Line 17

The else clause is optional; it is executed if no exception occurs in the try block.

Note

In this example, continue statements could have been used in the except blocks instead.

Line 19

The finally clause is optional; it is executed at the end of the block, regardless of whether an exception was thrown or not.