Jai*_*ime 6 python decorator argument-passing
我喜欢能够测量我编码的python函数的性能,所以我经常做类似的事情......
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
Run Code Online (Sandbox Code Playgroud)
是的,我知道你应该用timeit测量性能,但这对我的需求来说很好,并且允许我打开和关闭这些信息以便非常顺利地进行调试.
那段代码当然是在我了解函数装饰器之前...不是我现在对它们了解很多,但我想我可以使用**kwds字典编写一个装饰器来执行以下操作:
some_function(arg1, arg2, ..., argN) # Does not time function
some_function(arg1, arg2, ..., argN, verbose = True) # Times function
Run Code Online (Sandbox Code Playgroud)
不过,我想复制我的函数的先前工作,以便工作更像是:
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
Run Code Online (Sandbox Code Playgroud)
我想这需要装饰器计算参数的数量,知道原始函数需要多少,去掉任何多余的,将它们的正确数量传递给函数...我不知道如何告诉python做到这一点......有可能吗?有没有更好的方法来实现同样的目标?
虽然检查可以让你在路上了一下,你想要的是在一般没有可能的:
def f(*args):
pass
Run Code Online (Sandbox Code Playgroud)
现在需要多少参数f?由于*args并**kwargs允许任意数量的参数,因此无法确定函数所需的参数数量.事实上,有些情况下,函数真正处理的次数与抛出的次数一样多!
编辑:如果您愿意忍受verbose作为特殊关键字参数,您可以这样做:
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
def add(a, b):
return a + b
print(add(2, 2, verbose=True))
Run Code Online (Sandbox Code Playgroud)
(感谢亚历马尔泰利的kwargs.pop提示!)
然而,在Stephan202的答案上+1(将其放在一个单独的答案中,因为评论不能很好地格式化代码!),该答案中的以下代码:
verbose = False
if 'verbose' in kwargs:
verbose = True
del kwargs['verbose']
Run Code Online (Sandbox Code Playgroud)
可以更清晰,更简洁地表达为:
verbose = kwargs.pop('verbose', False)
Run Code Online (Sandbox Code Playgroud)