Dependency injection means passing an object’s dependencies from the outside instead of constructing them internally. It makes code easier to test and change.
Constructor Injection
class RobotControls:
def __init__(self, api):
self.api = api
def move_west(self):
self.api.send_command('move_west', data={'meters': 1})RobotControls depends on an object that has send_command. It does not need to know whether that object is a real API client, a mock, or a test double.
Benefit
The main benefit is substitutability. Tests can pass a fake dependency. Production code can pass the real dependency.
Cost
Constructor injection can create nested construction:
fence_guarding_robot = FenceGuardingRobot(RobotControls(RobotApi()))When object graphs grow, dependency construction may need a factory or container.
Inheritance Is Not The Same
Using inheritance and super() can reduce constructor nesting, but it changes the relationship. Inheritance means “is a”; dependency injection means “uses a”.
This connects to Python Inheritance And Polymorphism because inheritance should preserve substitutability. When a class only needs to use another service, composition through dependency injection is often cleaner.