Dependency Inversion Principle in Python


The Dependency Inversion Principle (DIP) is a fundamental principle of object-oriented design that promotes loose coupling between components and facilitates easier maintenance and extension of software systems. In this blog, we will discuss the Dependency Inversion Principle and provide an example in Python.
Understanding the Dependency Inversion Principle
The Dependency Inversion Principle is a part of the SOLID principles of object-oriented programming. It states that high-level modules should not depend on low-level modules, but both should depend on abstractions. In other words, classes should depend on interfaces or abstract classes rather than on concrete implementations.
The Dependency Inversion Principle can be summarized in the following statement: “Depend on abstractions, not on concretions.” This means that classes should depend on abstract types rather than on concrete types.
Example of the Dependency Inversion Principle in Python
Let’s consider an example to understand the Dependency Inversion Principle in Python. Suppose we have a class name Logger
that is responsible for logging messages. The Logger
class has a method called log
, which takes a message and logs it to a file. We also have a class named Calculator
that performs mathematical calculations. The Calculator
class uses the Logger
class to log messages.
Here is an example of how we can implement the Logger
and Calculator
classes in Python while violating the Dependency Inversion Principle:
class Logger:
def log(self, message):
with open('log.txt', 'a') as f:
f.write(message + '\n')
class Calculator:
def __init__(self):
self.logger = Logger()
def add(self, x, y):
result = x + y
self.logger.log(f"Added {x} and {y}, result = {result}")
return result
In this example, the Calculator
class depends on the Logger
class, which is a concrete implementation. This violates the Dependency Inversion Principle since the Calculator
class is dependent on a low-level module.
Here is an example of how we can implement the Logger
and Calculator
classes in Python while adhering to the Dependency Inversion Principle:
from abc import ABC, abstractmethod
class LoggerInterface(ABC):
@abstractmethod
def log(self, message):
pass
class Logger(LoggerInterface):
def log(self, message):
with open('log.txt', 'a') as f:
f.write(message + '\n')
class Calculator:
def __init__(self, logger: LoggerInterface):
self.logger = logger
def add(self, x, y):
result = x + y
self.logger.log(f"Added {x} and {y}, result = {result}")
return result
In this example, we have created an abstract class called LoggerInterface
, which defines a log
method. We have also modified the Calculator
class to accept a LoggerInterface
object as a dependency in its constructor. By doing this, the Calculator
class depends on an abstraction rather than on a concrete implementation of the Logger
class.
Conclusion
In conclusion, the Dependency Inversion Principle is a fundamental principle of object-oriented design that promotes loose coupling between components and facilitates easier maintenance and extension of software systems. By following to this principle, we can create software systems that are more flexible and maintainable.
Subscribe to my newsletter
Read articles from NonStop io Technologies directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

NonStop io Technologies
NonStop io Technologies
Product Development as an Expertise Since 2015 Founded in August 2015, we are a USA-based Bespoke Engineering Studio providing Product Development as an Expertise. With 80+ satisfied clients worldwide, we serve startups and enterprises across San Francisco, Seattle, New York, London, Pune, Bangalore, Tokyo and other prominent technology hubs.