Introduction
Exceptions occur when unexpected events disrupt the normal flow of program execution. Python has built-in exception handling constructs that allow gracefully handling errors and restoring normal flow. Proper exception handling is critical for developing robust programs in Python.
In this article, we will dive into Python exception concepts and exception handling in Python techniques with simple code examples.
What are Exceptions?
Exceptions, or runtime errors, are triggered when issues like missing files, network outages, invalid user input, division by zero etc. occur while a program is running.
For example, trying to open a non-existent file causes a FileNotFoundError
exception:
file = open('missing.txt') # Trigger FileNotFoundError
Exceptions immediately halt program execution and print a stack trace if not handled. Proper exception handling prevents abrupt crashes.
Exception Handling in python Using try…except
Catching Exceptions
We can catch and handle exceptions using try
and except
blocks:
try:
file = open('test.txt')
data = file.read()
file.close()
except FileNotFoundError:
print('File not found')
This gracefully handles the missing file instead of a crashing traceback.
We can specify different handling based on exception type:
try:
file = open('test.txt')
file.write('Hello') # Will cause Exception
x = 10/0 # Will cause ZeroDivisionError
except FileNotFoundError:
print('File not found')
except ZeroDivisionError:
print('Division by zero!')
The except
block that matches the exception type is executed. We can have multiple except
blocks to handle different failures differently.
Catching All Exceptions
We can use the root Exception
class to generically catch all exceptions:
try:
# Code that may have exceptions
except Exception as e:
print('An error occurred:', e)
raise # Optionally re-raise same exception
This prints the exception message without halting the program. The raise
keyword can be used to re-raise the same exception after handling.
Finally Block
The finally
block allows executing cleanup code that should always run, with or without exceptions:
try:
file = open('test.txt')
# Process file
except FileNotFoundError as e:
print('File not found')
finally:
print('Executing finally block')
The finally
block runs after normal execution or exception handling to release resources. This ensures critical cleanup like closing files always occurs.
Raising Exceptions in python
We can manually raise exceptions using the raise
keyword:
def check_age(age):
if age < 0:
raise ValueError('Age cannot be negative')
if age % 2 == 0:
print('Age is even')
check_age(-10) # Raises ValueError
Raising meaningful exceptions helps signal invalid program state.
Custom Exceptions in Python
Python also allows defining custom exception classes inheriting from Exception
:
class InvalidNameException(Exception):
pass
name = '123' # Invalid name
if not name.isalpha():
raise InvalidNameException
This enables raising exceptions in python specific to our application for clearer error handling.
Built-in Exceptions in Python
Python has many built-in exceptions that are raised automatically:
Exception | Cause |
---|---|
ZeroDivisionError | Division by zero |
OverflowError | Math operation exceeds max limit |
FileNotFoundError | File or directory not found |
ConnectionError | Network issue like DNS failure, refused connection |
ValueError | Invalid argument passed |
KeyError | Missing key for a dict or object |
AttributeError | Attribute reference fails |
ImportError | Import module fails |
KeyboardInterrupt | User interrupts program execution |
These common exceptions cover a wide variety of error scenarios.
Conclusion
Robust error handling with exceptions is critical for building reliable Python programs. The language provides simple yet powerful constructs like try-except-finally blocks and the raise keyword to implement exception handling. This allows detecting and recovering gracefully from unexpected events and invalid states instead of abrupt crashes. Mastering Python’s exception support results in fault-tolerant applications.
Frequently Asked Questions
- What happens when an exception is not caught in Python?
Uncaught exceptions in Python generate tracebacks and halt program execution. The stack trace helps debug the error.
- How do you catch multiple exceptions in Python?
Use multiple except blocks with the specific Exception classes to handle different errors differently.
- When should you use finally versus except blocks?
finally always runs after try/except to release resources. except runs only on matching exceptions.
- What is the purpose of raising exceptions in Python?
Raising exceptions helps signal abnormal conditions and invalid program states so they can be handled gracefully.
- How do you create a custom exception class in Python?
Custom exceptions can be defined by subclassing the built-in Exception class with custom logic.
- What are some common built-in exceptions in Python?
ZeroDivisionError, ValueError, FileNotFoundError, TypeError, ImportError etc. are some common built-in exceptions.
- What happens when you re-raise an exception in Python?
Using the raise statement without arguments re-raises the current exception being handled allowing outer handlers to catch it.
- Should all exceptions be caught and handled in Python?
It’s recommended to catch and handle exceptions that can be programatically recovered from. Some like KeyboardInterrupt may not need handling.
- What is the best way to print the exception message in Python?
Printing the exception object passed to the except block prints its message nicely – print(e).
- How do you handle multiple exceptions with the same handling logic?
Related exceptions can be grouped in a parent except block to reuse the same handling logic and simplify code.