9.1 try, except, else, and finally
Code that might fail is placed inside a try block. If an exception actually occurs, control immediately jumps to a matching except block — you can target a specific exception type, or use a broad Exception to catch nearly anything.
An optional else block runs only when the try block completed with absolutely no exception, which is useful for keeping "this only happens on success" logic cleanly separated from the risky code itself.
Finally, a finally block always runs — whether an exception happened or not — making it the standard, reliable place to put cleanup code, such as closing a file or a network connection.
A Complete try/except/else/finally Example
# A COMPLETE TRY/EXCEPT/ELSE/FINALLY
try:
result = 10 / int(input("Divide by: "))
except ZeroDivisionError:
print("Cannot divide by zero")
except ValueError:
print("Please enter a number")
else:
print(f"Result: {result}")
finally:
print("Done")
9.2 Raising & Creating Custom Exceptions
The raise statement lets your own code deliberately trigger an exception whenever something is wrong: raise ValueError("age cannot be negative").
Beyond Python's built-in exception types, you can define your own by inheriting from the built-in Exception class, giving your codebase clear, self-documenting, domain-specific error types instead of leaning only on generic built-ins.
A Custom Exception (from the Guide)
# A CUSTOM EXCEPTION
class InsufficientFundsError(Exception):
pass
def withdraw(balance, amount):
if amount > balance:
raise InsufficientFundsError("Not enough balance")
return balance - amount
try:
withdraw(100, 250)
except InsufficientFundsError as e:
print(f"Transaction failed: {e}")
💡 Pythonic Design: EAFP vs LBYL
Python culture strongly embraces EAFP ("Easier to Ask for Forgiveness than Permission") over LBYL ("Look Before You Leap"):
# LBYL (Defensive style common in C):
if key in my_dict:
val = my_dict[key]
# EAFP (Pythonic style):
try:
val = my_dict[key]
except KeyError:
val = None
EAFP avoids race conditions in multi-threaded environments and avoids double hash lookups!