I've used them for synchronization.
import functools
def synchronized(lock):
""" Synchronization decorator """
def wrap(f):
@functools.wraps(f)
def newFunction(*args, **kw):
lock.acquire()
try:
return f(*args, **kw)
finally:
lock.release()
return newFunction
return wrap
As pointed out in the comments, since Python 2.5 you can use a with statement in conjunction with a threading.Lock (or multiprocessing.Lock since version 2.6) object to simplify the decorator's implementation to just:
import functools
def synchronized(lock):
""" Synchronization decorator """
def wrap(f):
@functools.wraps(f)
def newFunction(*args, **kw):
with lock:
return f(*args, **kw)
return newFunction
return wrap
Regardless, you then use it like this:
import threading
lock = threading.Lock()
@synchronized(lock)
def do_something():
# etc
@synchronzied(lock)
def do_something_else():
# etc
Basically it just puts lock.acquire()
/ lock.release()
on either side of the function call.