Mastering Python Custom Exceptions: A Practical Guide
Python Custom Exceptions
In this tutorial, you will learn how to define custom exceptions tailored to your needs, illustrated with practical examples.
Python provides many built‑in exceptions that signal errors when a program encounters unexpected conditions. However, there are times when the built‑ins do not precisely describe the problem you’re encountering. In those cases, you can create your own custom exception types to make your code clearer and easier to maintain.
Creating Custom Exceptions
Defining a custom exception in Python is straightforward: create a new class that inherits from the built‑in Exception class (or one of its subclasses). Most of the standard exceptions are derived from Exception, so your custom class will integrate seamlessly with Python’s error‑handling system.
> >>> class CustomError(Exception):
... pass
...
>>> raise CustomError
Traceback (most recent call last):
...
__main__.CustomError
>>> raise CustomError("An error occurred")
Traceback (most recent call last):
...
__main__.CustomError: An error occurred
Here, CustomError is a user‑defined exception that inherits from Exception. It can be raised with raise and an optional message. When building large projects, it’s common practice to place all custom exceptions in a dedicated module (e.g., exceptions.py or errors.py) so that they’re easy to locate and maintain.
Example: User‑Defined Exception in Python
The following program demonstrates how custom exceptions can be used to guide user input. It repeatedly prompts the user for a number until they guess the stored value. The program provides a hint—whether the guess is too high or too low—by raising a tailored exception.
# define Python user‑defined exceptions
class Error(Exception):
"""Base class for other exceptions"""
pass
class ValueTooSmallError(Error):
"""Raised when the input value is too small"""
pass
class ValueTooLargeError(Error):
"""Raised when the input value is too large"""
pass
# the target number
number = 10
# keep asking until the guess is correct
while True:
try:
i_num = int(input("Enter a number: "))
if i_num < number:
raise ValueTooSmallError
elif i_num > number:
raise ValueTooLargeError
break
except ValueTooSmallError:
print("This value is too small, try again!")
print()
except ValueTooLargeError:
print("This value is too large, try again!")
print()
print("Congratulations! You guessed it correctly.")
Sample run:
Enter a number: 12 This value is too large, try again! Enter a number: 0 This value is too small, try again! Enter a number: 8 This value is too small, try again! Enter a number: 10 Congratulations! You guessed it correctly.
In this example, the base class Error provides a common ancestor for the two specific error types. This approach keeps the exception hierarchy clear and allows you to catch all related errors with a single except Error clause if desired.
Customizing Exception Classes
Custom exceptions can also store additional data or present more informative messages. This requires overriding __init__ and optionally __str__. The following illustrates a salary‑validation scenario.
class SalaryNotInRangeError(Exception):
"""Exception raised for errors in the input salary.
Attributes:
salary -- input salary which caused the error
message -- explanation of the error
"""
def __init__(self, salary, message="Salary is not in (5000, 15000) range"):
self.salary = salary
self.message = message
super().__init__(self.message)
salary = int(input("Enter salary amount: "))
if not 5000 < salary < 15000:
raise SalaryNotInRangeError(salary)
Output
Enter salary amount: 2000
Traceback (most recent call last):
File "<string>", line 17, in <module>
raise SalaryNotInRangeError(salary)
__main__.SalaryNotInRangeError: Salary is not in (5000, 15000) range
By overriding __init__, the exception can carry the offending value. If you want a custom string representation, override __str__ as shown below:
class SalaryNotInRangeError(Exception):
"""Exception raised for errors in the input salary.
Attributes:
salary -- input salary which caused the error
message -- explanation of the error
"""
def __init__(self, salary, message="Salary is not in (5000, 15000) range"):
self.salary = salary
self.message = message
super().__init__(self.message)
def __str__(self):
return f'{self.salary} → {self.message}'
salary = int(input("Enter salary amount: "))
if not 5000 < salary < 15000:
raise SalaryNotInRangeError(salary)
Output
Enter salary amount: 2000
Traceback (most recent call last):
File "/home/user/untitled.py", line 20, in <module>
raise SalaryNotInRangeError(salary)
__main__.SalaryNotInRangeError: 2000 → Salary is not in (5000, 15000) range
For a deeper dive into exception handling patterns, consult the Python Exception Handling tutorial.
To learn more about designing robust applications, explore Python Object‑Oriented Programming.
Python
- Mastering Python Errors & Built‑In Exceptions
- Mastering Python Object‑Oriented Programming: Classes, Inheritance, Encapsulation & Polymorphism
- Mastering Python Objects & Classes: A Practical Guide
- Mastering Python Inheritance: Concepts, Syntax, and Practical Examples
- Master Python Multiple Inheritance, Multilevel Inheritance, and Method Resolution Order (MRO)
- Avoiding Common Pitfalls: Proper Exception Handling in Python
- Mastering Python Class Slots: Optimize Memory & Speed
- Python Data Classes: Streamline Data Management with Modern Syntax
- Master Python Exception Handling: A Comprehensive Guide
- Master Python's Object-Oriented Programming: A Comprehensive Guide