Python · Course navigation

Python composition and object relationships

Build behavior by containing another object.

On this page
Before you start

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

Python
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())
Output
Engine ready; car ready

Follow the code

Open the walkthrough to inspect the example one step at a time.

Show guided walkthrough
Guided walkthroughReady
1class Engine:
2 def start(self):
3 return "Engine ready"
4
5class Car:
6 def __init__(self, engine):
7 self.engine = engine
8 def start(self):
9 return self.engine.start() + "; car ready"
10
11car = Car(Engine())
12print(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
Prepared trace of the published program. Some rows group repeated iterations.
Step / lineWhat happensState after stepOutput 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.

Further reading