我喜欢能够测量我编写的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是的,我知道你应该用timeit来测量性能,但这对我的需求很好,并且允许我非常顺利地打开和关闭这些信息以进行调试。
当然,这些代码是在我了解函数装饰器之前编写的。虽然我现在对它们了解不多,但我认为我可以使用**kwds字典编写一个完成以下任务的装饰器:
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我猜这将需要装饰者计算参数的数量,知道原始函数将接受多少参数,去掉多余的参数,将正确数量的参数传递给函数……不过,我不确定如何告诉python这样做...有可能吗?有没有更好的方法来实现同样的目标?
发布于 2009-05-20 17:12:34
尽管inspect可能会让你有点头疼,但你想要的通常是不可能的:
def f(*args):
pass现在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))(感谢Alex Martelli的kwargs.pop提示!)
发布于 2009-05-20 17:34:31
然而,在斯蒂芬202的答案上+1 (将这个放在一个单独的答案中,因为注释不能很好地格式化代码!),该答案中的以下代码:
verbose = False
if 'verbose' in kwargs:
verbose = True
del kwargs['verbose']可以更清楚、更简洁地表达为:
verbose = kwargs.pop('verbose', False)发布于 2009-05-20 17:34:35
这可能很难,但你可以在这些行上做一些事情。下面的代码尝试删除任何多余的参数并将其打印出来。
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']https://stackoverflow.com/questions/889088
复制相似问题