函数的递归版本在装饰时失败

  • 本文关键字:失败 递归 版本 函数 python
  • 更新时间 :
  • 英文 :


>我有以下代码,由于某种原因,正在修饰的函数的递归版本失败,出现以下异常

TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'

这是我的代码

def deco_func(f):
def wrapper(*args):
print('Decorating')
res = f(*args)
print(res)
print('Done !!')
return wrapper
@deco_func
def fact(n):
# res = 1
# for i in range(n, 0, -1):
#     res = res * i
#return res
if n > 0:
return n * fact(n-1)
else:
return 1
fact(5)

观察到的另一件事是,每次调用函数f时,语句print('Decorating')也会运行。

这让我发疯,我在这里迷路了,因为一旦函数fact被装饰,它就会获得wrapper object的值,当我们调用fact(6)时,它实际上是在调用wrapper(6),在它的主体内部,wrapper函数正在调用函数对象f这实际上是原始fact, 令人困惑的部分是调用f(*args)如何以及为什么将控件发送回wrapper函数,以及为什么它每次都打印 print 语句,因为事情f来自封闭范围并且应该保留其值,因为 python 为其创建了闭包。

第二件事,我尝试调试代码,一旦 n 的值达到 0,它就会返回值 1 到res然后突然n再次变为 1,并在下面一行抛出异常

return n * fact(n-1)

谁能解释一下这里到底发生了什么,以及我在概念上到底错过了什么!!

return(res)添加到包装函数中。任何无法执行return语句的 python 函数都会隐式返回None

执行调用时:

return n * fact(n-1)

凭借您的装饰器,这真的是:

return n * wrapper(n-1)

但是,由于wrapper()返回None语句如下所示:

return n * None

因此,您的错误消息:

TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'

这是你的装饰器,固定的。

def deco_func(f):
def wrapper(*args):
print('Decorating')
res = f(*args)
print(res)
print('Done !!')
return res       # <--- ADD THIS LINE
return wrapper

最新更新