gpt4 book ai didi

python - 递归Python函数的值修 retrofit 饰器

转载 作者:行者123 更新时间:2023-11-28 22:48:38 25 4
gpt4 key购买 nike

我正在尝试用 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com