from __future__ import with_statement import threading class synchronized(object): def __init__(self, obj=None): if obj is None: # decorator in classes self._lock = None return if isinstance(obj, threading._RLock): # decorator from functions self._lock = obj return # with statement if not hasattr(obj, '_kaa_synchronized_lock'): obj._kaa_synchronized_lock = threading.RLock() self._lock = obj._kaa_synchronized_lock def __enter__(self): self._lock.acquire() def __exit__(self, type, value, traceback): self._lock.release() def __call__(self, func): def call(*args, **kwargs): lock = self._lock if lock is None: # first parameter is self obj = args[0] if not hasattr(obj, '_kaa_synchronized_lock'): obj._kaa_synchronized_lock = threading.RLock() lock = obj._kaa_synchronized_lock lock.acquire() try: return func(*args, **kwargs) finally: lock.release() return call class Test(object): def foo(self): with synchronized(self): print 5 @synchronized() def bar(self, x, y): print 1, x, y lock = threading.RLock() @synchronized(lock) def foo(): print 6 t = Test() t.bar(5, 9) t.foo() t2 = Test() t2.foo() foo()