I would like design a python module so that its features can be modified by means of subclassing. This pattern is for instance used by the unittest module where you make a subclass of unittest.TestCase and define your tests as methods on this class. When unittest.main() is executed are these methods somehow run.
How do you design a module to allow modification by subclassing in this way?
I made the following module which allows modification of its behavior by subclassing the class MyRangeA. This implementation uses the magic methods __new__ and __sublasses__. It works as far as I can tell but I would like to know if there is a better way or if there are some issues with this way.
class MyRangeA: def __new__(cls, upper_limit): if cls.__subclasses__(): assert len(cls.__subclasses__()) == 1,\ f"Expected not more than one subclass of {cls} but the following exist:\n{cls.__subclasses__()}" subclass = cls.__subclasses__().pop() return super().__new__(subclass) else: return super().__new__(cls) def __init__(self, upper_limit): self._upper_limit = upper_limit def __iter__(self): return iter(range(self._upper_limit))def print_my_range(): print(str.join(", ", [str(num) for num in MyRangeA(3)]))
The client code could look like this:
from dunder_new import MyRangeA, print_my_rangeclass MyRangeB(MyRangeA): def __iter__(self): return iter(range(1, self._upper_limit + 1))print_my_range()
The client code modifies print_my_range so that "1, 2, 3" is printed instead of "0, 1, 2".