title: Count number of instances using a metaclass in Python
body: <p>I've written a <em>metaclass</em> which counts the number of instances for each of its children class.
  So my <em>meta</em> has a <em>dict</em> like <code>{classname: number_of_instances}</code>.</p>
  <p>This is the implementation:</p>
  <pre><code>class MetaCounter(type):
      
      _counter = {}
  
      def __new__(cls, name, bases, dict):
          cls._counter[name] = 0
          return super().__new__(cls, name, bases, dict)
  
      def __call__(cls, *args, **kwargs):
          cls._counter[cls.__name__] += 1
          print(f'Instantiated {cls._counter[cls.__name__]} objects of class {cls}!')
          return super().__call__(*args, **kwargs)
  
  
  
  class Foo(metaclass=MetaCounter):
      pass
  
  
  class Bar(metaclass=MetaCounter):
      pass
  
  
  x = Foo()
  y = Foo()
  z = Foo()
  a = Bar()
  b = Bar()
  print(MetaCounter._counter)
  # {'Foo': 3, 'Bar': 2} --&gt; OK!
  print(Foo._counter)
  # {'Foo': 3, 'Bar': 2} --&gt; I'd like it printed just &quot;3&quot;
  print(Bar._counter) 
  # {'Foo': 3, 'Bar': 2} --&gt; I'd like it printed just &quot;2&quot;
  </code></pre>
  <p>It works fine but I want to add a level of information hiding. That is, classes whom <em>metaclass</em> is <strong>MetaCounter</strong> should not have the counter of instances of other classes with the same meta. They should just have the information regarding the number of <strong>their</strong> instances.
  So <code>MetaCounter._counter</code> should display the entire <em>dict</em>, but <code>Foo._counter</code> (let <em>Foo</em> be a class with <em>MetaCounter</em> as its <em>metaclass</em>) should just return the number of <em>Foo</em> instances.</p>
  <p>Is there a way to achieve this?</p>
  <p>I've tried to override <code>__getattribute__</code> but it ended in messing around with the counting logic.</p>
  <p>I've also tried to put <code>_counter</code> as attribute in the <code>dict</code> parameter of the <code>__new__</code> method, but then it became also an instance member and I didn't want so.</p>