作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试用 Python 制作一个计时装饰器。它是这样工作的:
def function_timer(f):
"""
Creates an function timer wrapper around a function.
This is meant to be used as a decorator (see PEP 318).
Input:
f :: any function
Output:
A function that, when called, executes f with any arguments, while timing
the execution. The return value of this function depends on the return
value of f. If f returns
None ::
then this function returns None
a dictionary d ::
then this function returns a new dictionary with all the contents of
d, but with an additional key 'time' equal to the execution time of
the function. If the key 'time' is taken in the original dictionary,
then 'time_' will be tried, then 'time__', etc., until a free key is
found. The original dictionary will be shallow-copied, not modified.
some non-dict value x:
then this function returns a dictionary whose 'result' key gives x,
and whose 'time' key gives the execution time of the function.
"""
def timed_function(*args, **kwargs):
start_time = time.time()
print args, kwargs
result = f(*args, **kwargs)
end_time = time.time()
total_time = end_time - start_time
if result is None:
return None
elif type(result) >= dict:
result = result.copy()
key = 'time'
while key in result:
key += '_'
result[key] = total_time
else:
return { 'result': result, 'time': total_time }
return timed_function
这适用于简单的功能。但是当我在非内存斐波那契之类的函数上尝试时
@function_timer
def fib(n):
if n < 2:
return 1
else:
return fib(n - 2) + fib(n - 1)
它失败了,因为它递归:
fib(0)
和 fib(1)
返回 1
{ 'result': 1, 'time': 0.001 }
fib(2)
尝试添加 fib(0) + fib(1)
,即
{ 'result': 1, 'time': 0.001 } + { 'result': 1, 'time': 0.001 }
这失败了。
如何让装饰器只装饰函数的最终返回值?我根本不想修改 fib
函数。
最佳答案
如果您使用 function_timer
函数作为装饰器,它会为您不需要的 fib
函数的每次调用计时。您可能想要计算执行所有斐波那契函数所需的累计时间。
正如@minitech 所建议的,您可以通过function_timer
函数简单地包装斐波那契函数。
start_time = time.time()
result = fib(*args, **kwargs)
end_time = time.time()
上面的第二行只会在所有递归完成后返回,end_time - start_time
将准确反射(reflect)执行时间。
您可能没有意识到这一点,但是装饰器 f
包装了一个函数 g
,如下所示:f(g(x))
。在您的情况下,您不希望每次调用都用 f
包装 g
。您只需要一次,因此装饰器在这里不是很有用。
关于python - 递归Python函数的值修 retrofit 饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24836901/
我是一名优秀的程序员,十分优秀!