1

I have made an abstract base class using metaclass=ABCMeta to implement some default methods and properties that all its derived classes should have, something like this:

class BaseClass(metaclass=ABCMeta):

    def __init__(self):
        self.params = OrderedDict()

    # some function all children must implement
    @abstractmethod
    def fn():
        pass

    # some property all children will have
    @property
    def n_params(self):
        return len(self.params)

Now, I want to count how many instances of each derived class are created, because I want to print their name with a number. I can easily implement it like this:

class ChildClass(BaseClass):
    # nr of instances of ChildClass
    _n = 0

    def __init__(self, mu, sigma, amp):
        # initialize ABC
        super().__init__()

        ChildClass._n += 1        
        self.name = f'ChildClass {ChildClass._n}'

    # must be overridden by each child class
    @staticmethod
    def fn(name):
        # do stuff
        print(f'hello {name}')

However, I need to implement this in each class that derives from BaseClass separately. It would be much more elegant to implement it in BaseClass itself.

I am looking for something that works like the opposite of super(), maybe something like this:

class BaseClass(metaclass=ABCMeta):
    # instance counter for derived classes
    child()._n = 0
    def __init__(self):
        self.params = OrderedDict()

        child()._n += 1

Can I implement a class level variable ChildClass._n in BaseClass? And if so, how can I access that variable in BaseClass.__init__?

Edit: To clarify: I already have a base class, from which I derive many other child classes. The fact that all these classes share many properties is one of the main reasons I decided to use a base class in the first place. It thus seems superfluous to need to implement something as simple as an instance counter separately in each derived class.

Accessing a child class variable seems to be already adressed here. The question that remains is, how do I define a class level variable in my abstract base class, that is different for each child class.

MTV DNA
  • 187
  • 7
  • You can use a `metaclass` . Check out https://stackoverflow.com/a/30019359/2867928 – Mazdak Jun 11 '18 at 13:50
  • Ok, but then I still need to do that separately for every class that derives from `BaseClass`, which doesn't really solve my problem. I would really prefer to define it in `BaseClass` itself, and as far as I know `BaseClass` cannot have two metaclasses. – MTV DNA Jun 11 '18 at 14:55
  • In the mean time I have found a solution, but I cannot seem to post an answer myself. By setting `_n = 0` as a class variable of `BaseClass`, and then using `self.__class__._n += 1` in `BaseClass.__init__`, I get counters that are different for each derived child. – MTV DNA Jun 11 '18 at 17:07
  • Please see another duplicate attached to the question. – Mazdak Jun 11 '18 at 17:20

0 Answers0