Exception Handling in Python
Exception handling in Python is a mechanism to handle runtime errors, allowing the program to continue executing even when an error occurs. Python provides several built-in exceptions and the ability to create custom exceptions. The primary constructs for exception handling in Python are `try`, `except`, `else`, and `finally`.
### Basic Syntax
```python
try:
# Code that might raise an exception
risky_code()
except SomeException as e:
# Code that runs if SomeException occurs
handle_exception(e)
else:
# Code that runs if no exception occurs
no_exception_occurred()
finally:
# Code that runs no matter what
always_run()
```
### Key Components
1. **`try` Block**:
- Contains the code that might raise an exception.
- If an exception occurs, the rest of the `try` block is skipped, and the corresponding `except` block is executed.
2. **`except` Block**:
- Catches and handles the exception.
- You can specify the type of exception to catch (e.g., `ValueError`, `TypeError`).
- You can also catch multiple exceptions by using a tuple.
3. **`else` Block**:
- Executes if no exceptions are raised in the `try` block.
- This block is optional.
4. **`finally` Block**:
- Always executes, regardless of whether an exception was raised or not.
- This block is typically used for cleanup actions, such as closing files or releasing resources.
### Example
```python
def divide(a, b):
try:
result = a / b
except ZeroDivisionError as e:
print(f"Error: {e}")
except TypeError as e:
print(f"Error: {e}")
else:
print(f"The result is {result}")
finally:
print("Execution complete.")
divide(10, 2) # Output: The result is 5.0, Execution complete.
divide(10, 0) # Output: Error: division by zero, Execution complete.
divide(10, 'a') # Output: Error: unsupported operand type(s) for /: 'int' and 'str', Execution complete.
```
### Custom Exceptions
You can define custom exceptions by creating a new class that inherits from Python's built-in `Exception` class.
```python
class CustomError(Exception):
pass
def risky_function():
raise CustomError("Something went wrong!")
try:
risky_function()
except CustomError as e:
print(f"Caught an error: {e}")
```
### Raising Exceptions
You can manually raise exceptions using the `raise` keyword.
```python
def validate_age(age):
if age < 0:
raise ValueError("Age cannot be negative.")
elif age < 18:
raise ValueError("You must be at least 18 years old.")
try:
validate_age(-5)
except ValueError as e:
print(f"Invalid age: {e}")
```
### Best Practices
1. **Be Specific with Exceptions**: Catch specific exceptions rather than using a bare `except:` clause, as it can mask unexpected errors.
2. **Use `finally` for Cleanup**: Ensure resources are properly released using the `finally` block.
3. **Avoid Silent Catches**: Always log or handle exceptions appropriately; silently catching exceptions can make debugging difficult.
4. **Document Exceptions**: Clearly document the exceptions that a function or method can raise.
### Common Built-in Exceptions
- `ValueError`: Raised when a function receives an argument of the correct type but an inappropriate value.
- `TypeError`: Raised when an operation or function is applied to an object of an inappropriate type.
- `IndexError`: Raised when a sequence subscript is out of range.
- `KeyError`: Raised when a dictionary key is not found.
- `FileNotFoundError`: Raised when a file or directory is requested but doesn’t exist.
- `ZeroDivisionError`: Raised when division or modulo by zero occurs.
By effectively using exception handling, you can make your Python programs more robust and easier to debug.
Comments
Post a Comment