title: Given a method, how do I return the class it belongs to in Python 3.3 onward?
body: <p>Given <code>x = C.f</code> after:</p>
  
  <pre><code>class C:
      def f(self):
          pass
  </code></pre>
  
  <p>What do I call on <code>x</code> that will return <code>C</code>?</p>
  
  <p>The best I could do is <code>exec</code>ing a parsed portion of <code>x.__qualname__</code>, which is ugly:</p>
  
  <pre><code>exec('d = ' + ".".join(x.__qualname__.split('.')[:-1]))
  </code></pre>
  
  <p>For a use case, imagine that I want a decorator that adds a <code>super</code> call to any method it's applied to. How can that decorator, which is only given the function object, get the class to <code>super</code> (the <code>???</code> below)?</p>
  
  <pre><code>def ensure_finished(iterator):
      try:
          next(iterator)
      except StopIteration:
          return
      else:
          raise RuntimeError
  
  def derived_generator(method):
      def new_method(self, *args, **kwargs):
          x = method(self, *args, **kwargs)
          y = getattr(super(???, self), method.__name__)\
              (*args, **kwargs)
  
          for a, b in zip(x, y):
              assert a is None and b is None
              yield
  
          ensure_finished(x)
          ensure_finished(y)
  
      return new_method
  </code></pre>