Module lessons (4/4)
Error handling: try/except
When something goes wrong at runtime (a division by zero, a missing key, an
operation on incompatible types) Python raises an exception. Without
handling, the exception interrupts the program. With try / except you
can catch it and decide what to do.
The basic form
try:
risultato = 10 / 0
except ZeroDivisionError:
risultato = None
risultato # None- the
try:block contains the code that may fail; - the
except <ErrorType>:is executed only if that error type is raised inside thetry.
Catching the exception message
Use as to bind the exception object to a name:
try:
int("non è un numero")
except ValueError as e:
messaggio = str(e)
messaggio # "invalid literal for int() with base 10: 'non è un numero'"Multiple types together
try:
valore = dati[chiave]
except (KeyError, IndexError):
valore = NoneA tuple of types catches any exception of those types (or subclasses).
The full structure: try / except / else / finally
try:
n = int("42")
except ValueError:
print("not a number")
else:
print(f"parsed: {n}") # executed only if NO exception occurred
finally:
print("always executed") # executed regardless, even on exceptionelse— use it for code that depends on the success of thetry. Keep it separate so you don't accidentally catch unrelated exceptions.finally— cleanup that must always happen (closing a file, releasing a resource). Executed both on success and on error.
Raising an exception: raise
Sometimes you are the one who wants to signal that something went wrong:
def diviso(a, b):
if b == 0:
raise ValueError("the divisor cannot be zero")
return a / bThe most common built-in exceptions you will encounter and raise:
ValueError— the value has the right type but is unacceptable (e.g. parsing).TypeError— the type is wrong (e.g.len(42)).KeyError/IndexError— missing key/index.ZeroDivisionError— division by zero.FileNotFoundError,PermissionError— filesystem operations.
The else and finally clauses in try blocks
A try block can define two additional clauses:
else: executed only if thetryblock completes without raising any exceptions.finally: executed always, regardless of whether an exception occurred. This is ideal for cleaning up resources (e.g. closing an open file or database connection).
Try it yourself
Write an expression that tries int('abc'): if ValueError is raised, assign the string 'errore' to `result`; otherwise assign the number. Evaluate `result`.
Show hint
int('abc') raises ValueError.
Solution available after 3 attempts
Review exercise
Define `divide(a, b)` which returns a/b but raises ValueError with message 'divisore zero' if b is 0. Then call divide(10, 0) inside a try/except and assign to `message` the string of the caught exception.
Show hint
raise ValueError('...') inside the function; catch with except ValueError as e.
Solution available after 3 attempts
Additional challenge
Write a `try-except` block to convert the string `text_val = "abc"` to an integer. If the conversion raises a `ValueError`, assign `None` to `result`. Otherwise, assign the converted number. Finally, evaluate `result`.
Show hint
Use try: result = int(text_val) followed by except ValueError: result = None.
Solution available after 3 attempts