鱼C论坛

 找回密码
 立即注册
查看: 954|回复: 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 有求解精神

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

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

如果你确实需要计算较大的斐波那契数列,可以使用迭代的方式来计算,这样可以避免递归调用带来的性能问题。以下是一个使用迭代方式计算斐波那契数列的示例代码:
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 iterfibrecur(n):
    if n == 1 or n == 2:
        return 1
    x, y = 1, 1
    for i in range(3, n + 1):
        x, y = y, x + y
    return y

print(iterfibrecur(34))

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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

def 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 outfunc

def 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 a

print(func1(fibrecur,30))
print(func2(newfibrecur,30))
想知道小甲鱼最近在做啥?请访问 -> 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 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-22 01:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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