Does the Python standard library have a shortcut for writing decorators which accept arguments?
For example, if I want to write a decorator like with_timeout(timeout):
@with_timeout(10.0)
def cook_eggs(eggs):
while not eggs.are_done():
eggs.cook()
I have to write something like:
def with_timeout(timeout):
_func = [None]
def with_timeout_helper(*args, **kwargs):
with Timeout(timeout):
return _func[0](*args, **kwargs)
def with_timeout_return(f):
return functools.wraps(f)(with_timeout_helper)
return with_timeout_return
But that's awfully verbose. Is there a shortcut which makes decorators which accept arguments easier to write?
Note: I realize that it's also possible to use three nested functions to implement decorators with arguments… But that feels just a bit suboptimal too.
For example, possibly something like a @decorator_with_arguments function:
@decorator_with_arguments
def timeout(f, timeout):
@functools.wraps(f)
def timeout_helper(*args, **kwargs):
with Timeout(timeout):
return f(*args, **kwargs)
return timeout_helper
解决方案
I tend to write my decorators as classes to be honest
class TestWithArgs(object):
def __init__(self, *deco_args, **deco_kwargs):
self.deco_args = deco_args
self.deco_kwargs = deco_kwargs
def __call__(self, func):
def _wrap(self, *args, **kwargs):
print "Blah blah blah"
return func(*args, **kwargs)
return _wrap
Its nothing if not slightly clearer