鱼C论坛

 找回密码
 立即注册
查看: 1534|回复: 3

[已解决]装饰器语法糖装饰递归函数

[复制链接]
发表于 2024-1-22 12:29:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
求解,为什么运行不起来

import time

def timetest(num):
    def outfunc(thefunc):
        def insfunc():
            start = time.time()
            thefunc()
            end = time.time()
            print(f'{num}程序耗时{end-start:.2f}秒')
        return insfunc
    return outfunc

@timetest('原版')
def fibrecur(n):
    if n == 1 or n == 2:
        return 1
    else:
        return fibrecur(n-1)+ fibrecur(n-2)

@timetest('新版')
def newfibrecur(n,x=1,y=1):
    if n == 1 or n == 2:
        return y
    else:
        return newfibrecur(n-1,y,x+y)
        
print(fibrecur(34))
print(newfibrecur(34))
最佳答案
2024-1-22 13:59:38
Python入门者 发表于 2024-01-22 13:59
timetest装饰器中缺少可传入参数n,并且使用装饰器语 ...


你的代码已经进行了改进,现在timetest装饰器中可以接收可传入参数n,并且使用装饰器语法糖装饰递归函数。另外,你还通过添加一层函数进行包装,避免了装饰器重复调用的问题,这样确实可以避免产生多余的运行时间。代码看起来已经很完整了,但是有一个小问题:你在调用func1和func2时,传入的是30作为斐波那契数列的计算参数n,而不是34。你可以将第二个参数改为34以测试更大的斐波那契数列计算的效果。另外,你还可以添加更多的测试案例,尝试不同值的n,观察计算耗时。综合考虑以上因素,以下是经过改进的代码示例:import timedef timetest(num):    def outfunc(thefunc):        def insfunc(*n):            start = time.time()            result = thefunc(*n)            end = time.time()            print(f'{num}耗时{end-start:.2f}秒')            return result        return insfunc    return outfuncdef fibrecur(n):    if n == 1 or n == 2:        return 1    else:        return fibrecur(n-1) + fibrecur(n-2)def newfibrecur(n, x=1, y=1):    if n == 1 or n == 2:        return y    else:        return newfibrecur(n-1, y, x+y)@timetest('原版斐波那契数列生成器')def func1(func, n):    a = func(n)    return a@timetest('新版斐波那契数列生成器')def func2(func, n):    a = func(n)    return aprint(func1(fibrecur, 34))print(func2(newfibrecur, 34))在以上代码中,func1和func2分别接收斐波那契数列的生成函数和计算参数n,将计算结果返回,并通过装饰器打印出计算所耗费的时间。现在你可以运行该代码并观察结果。希望这次解答能满足你的需求,如果还有其他问题,欢迎继续提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

评分

参与人数 1荣誉 +1 收起 理由
METALARISING + 1 有求解精神

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-1-22 12:30:07 | 显示全部楼层
你的装饰器语法糖装饰递归函数的代码逻辑是正确的,但是由于斐波那契数列的计算复杂度较高,递归调用次数较多,导致计算时间较长。当计算到n=34时,递归调用的次数已经非常庞大,会耗费较长时间。

为了验证代码的运行情况,你可以先尝试运行较小的n值,比如n=10,来查看结果是否正常。

如果你确实需要计算较大的斐波那契数列,可以使用迭代的方式来计算,这样可以避免递归调用带来的性能问题。以下是一个使用迭代方式计算斐波那契数列的示例代码:

  1. import time

  2. def timetest(num):
  3.     def outfunc(thefunc):
  4.         def insfunc():
  5.             start = time.time()
  6.             thefunc()
  7.             end = time.time()
  8.             print(f'{num}程序耗时{end-start:.2f}秒')
  9.         return insfunc
  10.     return outfunc

  11. @timetest('迭代版')
  12. def iterfibrecur(n):
  13.     if n == 1 or n == 2:
  14.         return 1
  15.     x, y = 1, 1
  16.     for i in range(3, n + 1):
  17.         x, y = y, x + y
  18.     return y

  19. print(iterfibrecur(34))
复制代码


以上代码中,我们使用了迭代的方式来计算斐波那契数列,避免了递归调用,效率会更高一些。你可以尝试运行并比较不同版本的代码的执行时间。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-1-22 13:59:09 | 显示全部楼层
本帖最后由 Python入门者 于 2024-1-22 14:02 编辑

timetest装饰器中缺少可传入参数n,并且使用装饰器语法糖装饰递归函数,会导致装饰器重复调用,用一层函数进行包装避免重复调用就好了

  1. import time

  2. def timetest(num):
  3.     def outfunc(thefunc):
  4.         def insfunc(*n):
  5.             start = time.time()
  6.             result = thefunc(*n)
  7.             end = time.time()
  8.             print(f'{num}耗时{end-start:.2f}秒')
  9.             return result
  10.         return insfunc
  11.     return outfunc

  12. def fibrecur(n):
  13.     if n == 1 or n == 2:
  14.         return 1
  15.     else:
  16.         return fibrecur(n-1)+ fibrecur(n-2)

  17. def newfibrecur(n,x=1,y=1):
  18.     if n == 1 or n == 2:
  19.         return y
  20.     else:
  21.         return newfibrecur(n-1,y,x+y)

  22. @timetest('原版斐波那契数列生成器')
  23. def func1(func,n):
  24.     a = func(n)
  25.     return a

  26. @timetest('新版斐波那契数列生成器')
  27. def func2(func,n):
  28.     a = func(n)
  29.     return a

  30. print(func1(fibrecur,30))
  31. print(func2(newfibrecur,30))
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-22 13:59:38 | 显示全部楼层    本楼为最佳答案   
Python入门者 发表于 2024-01-22 13:59
timetest装饰器中缺少可传入参数n,并且使用装饰器语 ...


你的代码已经进行了改进,现在timetest装饰器中可以接收可传入参数n,并且使用装饰器语法糖装饰递归函数。另外,你还通过添加一层函数进行包装,避免了装饰器重复调用的问题,这样确实可以避免产生多余的运行时间。代码看起来已经很完整了,但是有一个小问题:你在调用func1和func2时,传入的是30作为斐波那契数列的计算参数n,而不是34。你可以将第二个参数改为34以测试更大的斐波那契数列计算的效果。另外,你还可以添加更多的测试案例,尝试不同值的n,观察计算耗时。综合考虑以上因素,以下是经过改进的代码示例:import timedef timetest(num):    def outfunc(thefunc):        def insfunc(*n):            start = time.time()            result = thefunc(*n)            end = time.time()            print(f'{num}耗时{end-start:.2f}秒')            return result        return insfunc    return outfuncdef fibrecur(n):    if n == 1 or n == 2:        return 1    else:        return fibrecur(n-1) + fibrecur(n-2)def newfibrecur(n, x=1, y=1):    if n == 1 or n == 2:        return y    else:        return newfibrecur(n-1, y, x+y)@timetest('原版斐波那契数列生成器')def func1(func, n):    a = func(n)    return a@timetest('新版斐波那契数列生成器')def func2(func, n):    a = func(n)    return aprint(func1(fibrecur, 34))print(func2(newfibrecur, 34))在以上代码中,func1和func2分别接收斐波那契数列的生成函数和计算参数n,将计算结果返回,并通过装饰器打印出计算所耗费的时间。现在你可以运行该代码并观察结果。希望这次解答能满足你的需求,如果还有其他问题,欢迎继续提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-22 20:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表