2022-05-26-递归加上装饰器,小心bug


一、原因

  1. 装饰器类似闭包,会给函数增加一些额外功能,具体功能可以在CSDN中查任何一篇blog,但是本片文章的blog主要是解决当目标函数(内置函数)是递归函数,该怎么处理???
  2. 因为直接在递归函数上面增加decorate,会导致decorate也发生递归,所以可以在递归函数和decorate中间加一个其他函数,就是不要中断递归函数,因为防止对象找不到,最后返回None
  3. 或者增加decorate中的wrap(狸猫)必须增加返回值,直接return fun(*wags)这样就可以是wrap在递归过程中能收集到返回值—(即使你目标函数(f1)有输入和输出,但是decorate中的fun也要有输入和输入(形式完整)真正做到了狸猫换太子

二、解决方案

1.中断出现None

代码如下(示例):

def decorate(fun):

    def wrap(*wags):

        fun(*wags)

    return wrap
@decorate
def f1(n):
    if n<2:
        return 1
    else:
        return f1(n-1)+f1(n-2)

print(f1(3))
#############返回None

2.利用第三函数

代码如下(示例):

def decorate(fun):
    def wrap(*wags):
        fun(*wags)
    return wrap
def f1(n):
    if n<2:
        return 1
    else:
        return f1(n-1)+f1(n-2)
@decorate
def f2(n):
    print(f1(n))

f2(5)
############返回值
8
price = {1: 1, 2: 1, 3: 8, 4: 9, 5: 10, 6: 17, 7: 17, 8: 20, 9: 24, 10: 30, 11: 35}

def memo(f):#debug点之一
    already_computed = {}  # 用来存储计算的最大值(某长度下),保证回到递归最外层有数据,即使在递归过程中遭到decoratede 的中断
    def _wrap(arg):
        if arg in already_computed:  # 检测是否之前已经算过
            result = already_computed[arg]  # 如果算过直接返回数值
        else:
            result = f(arg)  # 如果没有算过 调用r函数来计算数值
            already_computed[arg] = result  # 把结果存储到dic里面以供后面使用
        return result
    return _wrap
@memo

def r(n):#debug点之二

    max_price=max([price[n]] +[r(i) + r(n - i) for i in range(1, n)] )

    return max_price

print(r(3))#debug点之三

def decorate(fun):

    def wrap(*wags):狸猫换太子,调用目标函数,也要进行return ,否则返回None

        return fun(*wags)#必须return

    return wrap
@decorate
def f1(n):
    if n<2:
        return 1
    else:
        return f1(n-1)+f1(n-2)

print(f1(3))
############输出结果
3
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值