### 函数装饰器

``````import time

def some_function(arg1, arg2, ..., argN, verbose = True) :
t = time.clock() # works best in Windows
# t = time.time() # apparently works better in Linux

# Function code goes here

t = time.clock() - t
if verbose :
print "some_function executed in",t,"sec."

return return_val
``````

``````some_function(arg1, arg2, ..., argN) # Does not time function
some_function(arg1, arg2, ..., argN, verbose = True) # Times function
``````

``````some_function(arg1, arg2, ..., argN) # Does not time function
some_function(arg1, arg2, ..., argN, False) # Does not time function
some_function(arg1, arg2, ..., argN, True) # Times function
``````

#### 3 个答案:

``````def f(*args):
pass
``````

``````import time

def timed(f):
def dec(*args, **kwargs):
verbose = kwargs.pop('verbose', False)
t = time.clock()

ret = f(*args, **kwargs)

if verbose:
print("%s executed in %ds" % (f.__name__, time.clock() - t))

return ret

return dec

@timed
return a + b

``````

（感谢`kwargs.pop`获得{{1}}小费！）

+1（由于评论不能很好地格式化代码，因此将其放在一个单独的答案中），该答案中的以下代码：

``````verbose = False
if 'verbose' in kwargs:
verbose = True
del kwargs['verbose']
``````

``````verbose = kwargs.pop('verbose', False)
``````

``````def mydeco(func):
def wrap(*args, **kwargs):
"""
we want to eat any extra argument, so just count args and kwargs
and if more(>func.func_code.co_argcount) first take it out from kwargs
based on func.func_code.co_varnames, else last one from args
"""
extraArgs = []

newKwargs = {}
for name, value in kwargs.iteritems():
if name in func.func_code.co_varnames:
newKwargs[name] = value
else:
extraArgs.append(kwargs[name])

diff = len(args) + len(newKwargs) - func.func_code.co_argcount
if diff:
extraArgs.extend(args[-diff:])
args = args[:-diff]

func(*args, **newKwargs)
print "%s has extra args=%s"%(func.func_name, extraArgs)

return wrap

@mydeco
def func1(a, b, c=3):
pass

func1(1,b=2,c=3, d="x")
func1(1,2,3,"y")
``````

``````func1 has extra args=['x']
func1 has extra args=['y']
``````