一、原因
- 装饰器类似闭包,会给函数增加一些额外功能,具体功能可以在CSDN中查任何一篇blog,但是本片文章的blog主要是解决当目标函数(内置函数)是递归函数,该怎么处理???
- 因为直接在递归函数上面增加decorate,会导致decorate也发生递归,所以可以在递归函数和decorate中间加一个其他函数,就是不要中断递归函数,因为防止对象找不到,最后返回None
- 或者增加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