title: Possible to create a @synchronized decorator that's aware of a method's object?
body: <p>I'm trying to create a @synchronized wrapper that creates one Lock per object and makes method calls thread safe. I can only do this if I can access method.im_self of the method in the wrapped method.</p>
  
  <pre><code>    class B:
          def f(self): pass
  
      assert inspect.ismethod( B.f ) # OK
      assert inspect.ismethod( B().f ) # OK
      print B.f    # &lt;unbound method B.f&gt;
      print B().f  # &lt;bound method B.f of &lt;__main__.B instance at 0x7fa2055e67e8&gt;&gt;
  
  
  
      def synchronized(func):
          # func is not bound or unbound!
          print func  # &lt;function f at 0x7fa20561b9b0&gt;    !!!!
  
          assert inspect.ismethod(func)  # FAIL
          # ... allocate one lock per C instance
          return func
  
      class C:
          @synchronized
          def f(self): pass
  </code></pre>
  
  <p>(1) What's confusing is that the func parameter passed to my decorator changes type before it gets passed into the wrapper-generator. This seem is rude and unnecessary. Why does this happen?</p>
  
  <p>(2) Is there some decorator magic by which I can make method calls to an object mutex-ed (i.e. one lock per object, not per class).</p>
  
  <p>UPDATE: There are many examples of @synchronized(lock) wrappers. However, really what I want is @synchronized(self). I <em>can</em> solve it like this:</p>
  
  <pre><code>    def synchronizedMethod(func):
          def _synchronized(*args, **kw):
               self = args[0]
               lock = oneLockPerObject(self)
               with lock: return func(*args, **kw)
          return _synchronized
  </code></pre>
  
  <p>However, because its much more efficient, I'd prefer:</p>
  
  <pre><code>    def synchronizedMethod(func):
          lock = oneLockPerObject(func.im_self)
  
          def _synchronized(*args, **kw):
               with lock: return func(*args, **kw)
  
          return _synchronized
  </code></pre>
  
  <p>Is this possible?</p>