title: Counting calls to certain methods of a class and of any subclass
body: <p>I have a generic class that users are supposed to subclass in order to implement certain methods. There can be subclasses several levels deep. Something like</p>
  
  <pre><code>class Thing(object):
      def fun(self, *args, **kwargs):
          raise NotImplementedError()
  
  class Bell(Thing):
      def fun(self):
          return 1
  
  class Whistle(Bell):
      def fun(self):
          return super(Whistle, self).fun() + 1
  </code></pre>
  
  <p>I would like to count the number of times that <code>fun()</code> is called when any subclass of <code>Thing</code> is used. Because decorators aren't inherited, and because I don't want users to have to remember to decorate their <code>fun()</code> method, my understanding is that metaclasses are the way to go. So I wrote</p>
  
  <pre><code>class CountCalls(type):
  
      def __new__(cls, name, bases, attrs):
          attrs["_original_fun"] = attrs["fun"]
          attrs["fun"] = countcalls(attrs["_original_fun"])
          return super(CountCalls, cls).__new__(cls, name, bases, attrs)
  </code></pre>
  
  <p>where <code>countcalls</code> is the classic decorator to count the number of calls:</p>
  
  <pre><code>def countcalls(fn):
      def wrapper(*args, **kwargs):
          wrapper.ncalls += 1
          return fn(*args, **kwargs)
      wrapper.ncalls = 0
      wrapper.__name__ = fn.__name__
      wrapper.__doc__ = fn.__doc__
      return wrapper
  </code></pre>
  
  <p>and changed the definition of <code>Thing</code> to</p>
  
  <pre><code>class Thing(object):
  
      __metaclass__ = CountCalls
  
      def fun(self, *args, **kwargs):
          raise NotImplementedError()
  </code></pre>
  
  <p><strong>Problem</strong>: That works, but it has the unintended side effect of incrementing the number of calls counter of <em>all</em> instances when the <code>fun()</code> method of <em>any</em>  instance is called:</p>
  
  <pre><code>&gt;&gt;&gt; b1 = Bell()
  &gt;&gt;&gt; b2 = Bell()
  &gt;&gt;&gt; b1.fun.ncalls, b2.fun.ncalls
  (0, 0)
  &gt;&gt;&gt; b1.fun()
  1
  &gt;&gt;&gt; b1.fun.ncalls, b2.fun.ncalls
  (1, 1)
  </code></pre>
  
  <p><strong>Question</strong>: How do I count the number of calls to <code>fun()</code> on a per-instance basis? It feels like I should be implementing <code>__init__</code> instead of <code>__new__</code> in the metaclass, but so far I've not found the correct syntax. For example, using</p>
  
  <pre><code>def __init__(self, name, bases, attrs):
      attrs["_original_fun"] = attrs["fun"]
      attrs["fun"] = countcalls(attrs["_original_fun"])
      super(CountCalls, self).__init__(name, bases, attrs)
  </code></pre>
  
  <p>yields</p>
  
  <pre><code>&gt;&gt;&gt; b = Bell()
  &gt;&gt;&gt; b.fun.ncalls
  Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  AttributeError: 'function' object has no attribute 'ncalls'
  </code></pre>
  
  <p>Thanks!</p>