ruk·si

🐍 Python
Inheritance

Updated at 2017-01-02 23:22

Prefer composition over inheritance.

Understand the difference between interface inheritance and implementation inheritance. Interface inheritance creates "is-a" relationships, abstract base classes. Implementation inheritance allows code reuse, concrete classes and mixins.

Use mixins for code reuse. Mixin bundles methods for reuse, mixin does not define an "is-a" relationship. But even if mixins don't define type, they should have well defined purpose.

It's recommended to suffix your mixin names with ...Mixin.

Don't subclass from more than one concrete class. Only one subclass should be something other that abstract base class or mixin. Inheriting multiple concrete classes makes applications over complex.

class MyConcreteClass(Alpha, BaseBeta, GammaMixin):
    pass

Create aggregate classes. Aggregate classes don't have any body but group classes together for easier use.

class Widget(BaseWidget, PlaceMixin, GridMixin):
    pass

Avoid subclassing built-in types like list or dict Subclassing built-in types is tricky because extended built-in classes don't first search for methods on itself, thus ignoring user-defined overrides. If you need to subclass a built-in type, use e.g. collections.UserDict or collections.UserList.

class DoubleDict(dict):
    def __setitem__(self, key, value) -> None:
        super().__setitem__(key, [value] * 2)

dd = DoubleDict(one=1)
assert dd == {'one': 1}     # NOT duplicated

dd['two'] = 2
assert dd['two'] == [2, 2]  # ok, duplicated

dd.update(three=3)
assert dd['three'] == 3     # NOT duplicated

Source

  • Fluent Python, Luciano Ramalho