NotImplementedError is a built-in Python exception that is raised when a method or function has been declared but its implementation has not yet been provided. It is commonly used in abstract classes, base classes and during software development when a method is intended to be implemented later by subclasses.
class Shape:
def area(self):
raise NotImplementedError(
"Subclasses must implement area()"
)
shape = Shape()
shape.area()
Output
ERROR!
Traceback (most recent call last):
File "<main.py>", line 9, in <module>
File "<main.py>", line 4, in area
NotImplementedError: Subclasses must implement area()
Explanation:
- The Shape class contains an area() method.
- Instead of providing an implementation, it raises NotImplementedError.
- When area() is called, Python raises the exception because the method is not yet implemented.
Common Causes
1. Method Not Implemented in a Subclass: A common use of NotImplementedError is in a parent class where child classes are expected to provide their own implementation.
class Animal:
def sound(self):
raise NotImplementedError(
"Subclasses must implement sound()"
)
class Dog(Animal):
pass
dog = Dog()
dog.sound()
Output
ERROR!
Traceback (most recent call last):
File "<main.py>", line 12, in <module>
File "<main.py>", line 4, in sound
NotImplementedError: Subclasses must implement sound()
Explanation:
- Animal defines a method named sound().
- Dog inherits from Animal but does not override the method.
- Calling sound() executes the parent class method, which raises NotImplementedError.
2. Placeholder Methods During Development: Developers often use NotImplementedError as a placeholder while building an application.
class PaymentSystem:
def process_payment(self):
raise NotImplementedError(
"Payment functionality is under development"
)
payment = PaymentSystem()
payment.process_payment()
Output
ERROR!
Traceback (most recent call last):
File "<main.py>", line 9, in <module>
File "<main.py>", line 4, in process_payment
NotImplementedError: Payment functionality is under development
Explanation:
- The method has been created but its actual logic is not written yet.
- Raising NotImplementedError reminds developers that implementation is still pending.
3. Incomplete Class Hierarchy: Sometimes multiple subclasses are created, but one of them forgets to implement the required method.
class Vehicle:
def start(self):
raise NotImplementedError(
"Subclasses must implement start()"
)
class Car(Vehicle):
def start(self):
return "Car started"
class Bike(Vehicle):
pass
bike = Bike()
bike.start()
Output
ERROR!
Traceback (most recent call last):
File "<main.py>", line 17, in <module>
File "<main.py>", line 4, in start
NotImplementedError: Subclasses must implement start()
Explanation:
- Car correctly implements the start() method. Bike does not implement it.
- Therefore, Python uses the parent class method and raises NotImplementedError.
Handling NotImplementedError
1. Implement the Required Method: to avoid NotImplementedError is to provide a proper implementation of the method in the subclass. This ensures that when the method is called, Python executes the subclass-specific logic instead of raising an exception.
class Shape:
def area(self):
raise NotImplementedError(
"Subclasses must implement area()"
)
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side * self.side
square = Square(5)
print(square.area())
Output
25
Explanation:
- The Square class overrides the area() method.
- Since a proper implementation is provided, no exception is raised.
2. Abstract Base Classes: Python's abc module allows to define abstract methods that must be implemented by child classes. This helps enforce a consistent class structure and prevents the creation of incomplete subclasses that are missing required methods.
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
class Square(Shape):
def area(self):
return 25
square = Square()
print(square.area())
Output
25
Explanation:
- The @abstractmethod decorator marks the method as mandatory.
- Any subclass must implement it before objects can be created.
3. Handle the Exception Using try-except: In situations where a method may intentionally be left unimplemented, you can use a try-except block to catch NotImplementedError.
class Shape:
def area(self):
raise NotImplementedError(
"Subclasses must implement area()"
)
try:
shape = Shape()
shape.area()
except NotImplementedError as error:
print(error)
Output
Subclasses must implement area()
Explanation:
- The exception is raised inside the try block.
- The except block catches it and prints the error message instead of terminating the program.