Sometimes the use of inheritance is impractical or even impossible. This motivates the use of encapsulation.
We will explain the concept of encapsulation by considering Python functions, that is, objects of the Python type function, which we encapsulate in a new class, Function, and provide with some relevant methods:
class Function: def __init__(self, f): self.f = f def __call__(self, x): return self.f(x) def __add__(self, g): def sum(x): return self(x) + g(x) return type(self)(sum) def __mul__(self, g): def prod(x): return self.f(x) * g(x) return type(self)(prod) def __radd__(self, g): return self + g def __rmul__(self, g): return self * g
Note that the operations __add__ and __mul__ should return an instance of the same class. This is achieved by the statement return type(self)(sum), which in this case is a more general form of writing return Function...