Trying to understand oop in python I came into this situation that puzzles me, and I wasn't able to find a satisfactory explanation... I was building a Countable class, which has a counter attribute that counts how many instances of the class have been initialized. I want this counter to be increased also when a subclass (or subsubclass) of the given class is initialized. Here is my implementation:
class Countable(object):
    counter = 0
    def __new__(cls, *args, **kwargs):
        cls.increment_counter()
        count(cls)
        return object.__new__(cls, *args, **kwargs)
    @classmethod
    def increment_counter(cls):
        cls.counter += 1
        if cls.__base__ is not object:
            cls.__base__.increment_counter()
where count(cls) is there for debugging purposes, and later i write it down.
Now, let's have some subclasses of this:
class A(Countable):
    def __init__(self, a='a'):
        self.a = a
class B(Countable):
    def __init__(self, b='b'):
        self.b = b
class B2(B):
    def __init__(self, b2='b2'):
        self.b2 = b2
def count(cls):
    print('@{:<5}  Countables: {}  As: {}  Bs: {}  B2s: {}'
          ''.format(cls.__name__, Countable.counter, A.counter, B.counter, B2.counter))
when I run a code like the following:
a = A()
a = A()
a = A()
b = B()
b = B()
a = A()
b2 = B2()
b2 = B2()
I obtain the following output, which looks strange to me:
@A      Countables:  1  As: 1  Bs: 1  B2s: 1
@A      Countables:  2  As: 2  Bs: 2  B2s: 2
@A      Countables:  3  As: 3  Bs: 3  B2s: 3
@B      Countables:  4  As: 3  Bs: 4  B2s: 4
@B      Countables:  5  As: 3  Bs: 5  B2s: 5
@A      Countables:  6  As: 4  Bs: 5  B2s: 5
@B2     Countables:  7  As: 4  Bs: 6  B2s: 6
@B2     Countables:  8  As: 4  Bs: 7  B2s: 7
Why at the beginning both the counter of A and B is incrementing, despite I am calling only A()? And why after the first time I call B() it behaves like expected?
I already found out that to have a behavior like I want it is sufficient to add counter = 0 at each subclass, but I was not able to find an explanation of why it behaves like that.... Thank you!
I added few debug prints, and for simplicity limited class creation to two. This is pretty strange:
>>> a = A()
<class '__main__.A'> incrementing
increment parent of <class '__main__.A'> as well
<class '__main__.Countable'> incrementing
@A      Counters: 1  As: 1  Bs: 1  B2s: 1
>>> B.counter
1
>>> B.counter is A.counter
True
>>> b = B()
<class '__main__.B'> incrementing
increment parent of <class '__main__.B'> as well
<class '__main__.Countable'> incrementing
@B      Counters: 2  As: 1  Bs: 2  B2s: 2
>>> B.counter is A.counter
False
How come when B() is not initialized yet, it points to the same variable as A.counter but after creating single object it is a different one?
 
    