Template pattern

Following example show how to use Template pattern and hook methods to write clean abstractions.

class Bicycle:
    def __init__(self, size, chain, tire_size):
        self.size = size
        self.chain = chain
        self.tire_size = tire_size
        post_initialize(self)

    def post_initialize(self):
        pass

    def spares(self):
        return {
            'tire_size': self.tire_size,
            'chain': self.chain,
        }.update(self.local_spares())

    def local_spares(self):
        return {}

    def default_chain(self):
        return '10-speed'

    def default_tire_size(self):
        raise NotImplementedError()

class RoadBike(Bicycle):
    def post_initialize(self):
        self.tape_color = self.default_tape_color()

    def local_spares(self):
        return {
            'tape_color': self.tape_color,
        }

    def default_tire_size(self):
        return '23'

    def default_tape_color(self):
        return 'red'

class MountainBike(Bicycle):
    def post_initialize(self):
        self.front_shock = self.default_front_shock()
        self.rear_shock = self.default_rear_shock()

    def local_spares(self):
        return {
            'front_shock': self.front_shock,
            'rear_shock': self.rear_shock,
        }

    def default_tire_size(self):
        return '2.1'

    def default_front_shock(self):
        return 'Manitou'

    def default_rear_shock(self):
        return 'Fox'