Python composition and object relationships
Build behavior by containing another object.
On this page
Classes and constructors.
- Build behavior by containing another object.
- Predict the sample output and explain the state changes.
- Complete the practice task and check the boundary cases.
The concept
Composition models a has-a relationship. A Car delegates starting to its Engine instead of inheriting from Engine.
Passing the dependency into the constructor makes the relationship explicit and allows a different compatible engine to be supplied later.
Code example
class Engine:
def start(self):
return "Engine ready"
class Car:
def __init__(self, engine):
self.engine = engine
def start(self):
return self.engine.start() + "; car ready"
car = Car(Engine())
print(car.start())Engine ready; car ready
Follow the code
Open the walkthrough to inspect the example one step at a time.
Show guided walkthrough
class Engine: def start(self): return "Engine ready" class Car: def __init__(self, engine): self.engine = engine def start(self): return self.engine.start() + "; car ready" car = Car(Engine())print(car.start())Follow the example
Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.
View the complete dry-run table
| Step / line | What happens | State after step | Output so far |
|---|---|---|---|
| Create an Engine and pass it into Car. | car.engine = Engine instance | — | |
| Delegate to the contained engine. | car.engine = Engine instance | — | |
| Engine supplies its result. | engine result = Engine ready | — | |
| Combine and print the result. | engine result = Engine ready | Engine ready; car ready |
Behind the scenes
How Python processes this code
Python runs this source through its interpreter. It creates objects for values and resolves names as each statement runs.
Cost and common mistakes
O(1) calls for this fixed object relationship.
- Car is not a kind of Engine; inheritance would misrepresent this relationship.
- Sharing a mutable dependency means multiple owners can observe its changes.
Try it yourself
Replace Engine with a compatible ElectricMotor returning Motor ready.
Reveal answer and reasoning
Pass ElectricMotor() to Car. The result is Motor ready; car ready without changing Car.