liveBook · Manning

Inversion of control

As explained in Practices of the Python Pro

Inversion of control is a design technique in which control over object construction, behavior, or dependencies is transferred from a component to an external mechanism or caller.

Inversion of control makes software easier to extend by transferring dependency creation or behavior control from a class to its caller. Instead of constructing its own parts, a class receives objects it can use. This reduces rigid dependencies and lets existing code accommodate changing requirements. section 7.2.1 section 7.4

Swapping a bicycle frame

A rigid Bicycle creates its own Tire and Frame objects, so changing the frame requires editing Bicycle. Passing front_tire, back_tire, and frame into Bicycle lets the caller choose the implementations. A CarbonFiberFrame can then replace Frame without changing Bicycle, provided it offers the expected methods and attributes. section 7.2.1

Use inversion of control to:

  • Customize behavior without modifying low-level implementation. section 7.4
  • Replace real dependencies with test doubles to isolate class behavior. section 7.2.1
  • Extend application behavior with focused commands, such as preserving GitHub star timestamps. section 7.3
Listing 7.5. Using inversion of control
class Tire:
    def __repr__(self):
        return 'A rubber tire'


class Frame:
    def __repr__(self):
        return 'An aluminum frame'


class Bicycle:
    def __init__(self, front_tire, back_tire, frame):  #1
        self.front_tire = front_tire
        self.back_tire = back_tire
        self.frame = frame

    def print_specs(self):
        print(f'Frame: {self.frame}')
        print(f'Front tire: {self.front_tire}, back tire: {self.back_tire}')


if __name__ == '__main__':
    bike = Bicycle(Tire(), Tire(), Frame())            #2
    bike.print_specs()

Inspect the compact Python example that passes dependencies into Bicycle rather than constructing them internally. section 7.2.1

How Practices of the Python Pro covers it

How deep it goes
Defines dependency passing, demonstrates replacement and testing, and stops short of broader implementation frameworks.
Examples
Uses Bicycle parts, CarbonFiberFrame, MockTire, and a GitHub stars importer preserving bookmark timestamps.
What it assumes
Assumes basic Python classes, constructors, methods, and object creation while developing flexibility through short examples.
What you can do after
Apply dependency passing and optional behavior inputs to extend Python classes without editing their implementations.
How it connects
Connects dependencies with interfaces, testing, test doubles, extensibility, and coupling.

Also explained in

Compare how 3 books explain inversion of control →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Practices of the Python Pro. The section links point to the parts of the book it draws on.