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.
Note
The way Python handles error situations in general differs from some other languages, for example Java. These languages check possible errors as far as possible before they occur, as handling exceptions after they occur is costly. This is sometimes referred to as the LBYL approach.
Python, on the other hand, relies more on exceptions to handle errors after they occur. Although this reliance may seem risky, when exceptions are used correctly, the code is less cumbersome and easier to read, and errors are only handled when they occur. This Pythonic approach to error handling is often described as EAFP (Easier to ask forgiveness than permission).
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
IOErrororEmptyFileErroroccurs during the execution of the instructions in thetryblock, the correspondingexceptblock is executed.- Line 9
An
IOErrorcould be triggered here.- Line 12
Here you trigger the
EmptyFileError.- Line 17
The
elseclause is optional; it is executed if no exception occurs in thetryblock.Note
In this example,
continuestatements could have been used in theexceptblocks instead.- Line 19
The
finallyclause is optional; it is executed at the end of the block, regardless of whether an exception was thrown or not.
Checks¶
Write code that receives two numbers and divides the first number by the second. Check if the
ZeroDivisionErroroccurs when the second number is0and catch it.If
MyErrorinherits fromException, what is the difference betweenexcept Exception as eandexcept MyError as e?The first catches every exception that inherits from
Exception, while the second only catchesMyErrorexceptions.Write a simple program that receives a number and then uses the
assert()statement to throw anExceptionif the number is0.Write a user-defined exception
outliersthat throws anExceptionif the variablexis greater or less than3?Is checking whether an object is a list (Check: Listen) programming in the style of LBYL or EAFP?