PythiloLesson 15 of 30 · progress kept in this browser

Composition and mixins

Inheritance says "is a": a square is a shape. Composition says "has a": a car has an engine, stored as an attribute, and the car hands work to it. Prefer composition by default. Parts can be swapped at runtime or in tests, and a change to one part does not ripple through a hierarchy.

import json

class JsonMixin:
    def to_json(self):
        return json.dumps(vars(self))

class Point(JsonMixin):
    def __init__(self, x, y):
        self.x, self.y = x, y

class Engine:
    def start(self):
        return "vroom"

class Car:
    def __init__(self, engine):
        self.engine = engine

    def start(self):
        return self.engine.start()

print(Point(1, 2).to_json())
print(Car(Engine()).start())
Your task

Finish ReprMixin, whose repr shows the class name and every instance attribute as keyword arguments, like Item(name='pen', price=2), and EqualityMixin, under which objects of the same class are equal when their attributes are. Change Notifier to receive a sender object in __init__, anything with send(text), instead of inheriting from EmailSender.

Next: Descriptors