title: Python decorator, self is mixed up
body: <p>I am new to Python decorators (wow, great feature!), and I have trouble getting the following to work because the <code>self</code> argument gets sort of mixed up.</p>
  
  <pre><code>#this is the decorator
  class cacher(object):
  
      def __init__(self, f):
          self.f = f
          self.cache = {}
  
      def __call__(self, *args):
          fname = self.f.__name__
          if (fname not in self.cache):
              self.cache[fname] = self.f(self,*args)
          else:
              print "using cache"
          return self.cache[fname]
  
  class Session(p.Session):
  
      def __init__(self, user, passw):
          self.pl = p.Session(user, passw)
  
      @cacher
      def get_something(self):
          print "get_something called with self = %s "% self
          return self.pl.get_something()
  
  s = Session(u,p)
  s.get_something()
  </code></pre>
  
  <p>When I run this, I get:</p>
  
  <pre><code>get_something called with self = &lt;__main__.cacher object at 0x020870F0&gt; 
  Traceback:
  ...
  AttributeError: 'cacher' object has no attribute 'pl'
  </code></pre>
  
  <p>for the line where I do <code>self.cache[fname] = self.f(self,*args)</code></p>
  
  <p><strong>The problem</strong> - Obviously, the problem is that <code>self</code> is the cacher object instead of a Session instance, which indeed doesn't have a <code>pl</code> attribute. However I can't find how to solve this. </p>
  
  <p><strong>Solutions I've considered, but can't use</strong> - I thought of making the decorator class return a function instead of a value (like in section 2.1 of this <a href="http://www.siafoo.net/article/68#the-wrapper-function" rel="nofollow noreferrer">article</a>) so that <code>self</code> is evaluated in the right context, but that isn't possible since my decorator is implemented as a class and uses the build-in  <code>__call__</code> method. Then I thought to <em>not</em> use a class for my decorator, so that I don't need the __call__method, but I can't do that because I need to keep state between decorator calls (i.e. for keeping track of what is in the <code>self.cache</code> attribute).</p>
  
  <p><strong>Question</strong> - So, apart from using a global <code>cache</code> dictionary variable (which I didn't try, but assume will work), is there any other way to make this decorator work? </p>
  
  <p>Edit: this SO question seems similar <a href="https://stackoverflow.com/questions/2365701/decorating-python-class-methods-how-do-i-pass-the-instance-to-the-decorator">Decorating python class methods, how do I pass the instance to the decorator?</a></p>