我有以下代码,由于某种原因,递归版本正在修饰的函数失败,并带有以下异常
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)
另一件事是,每次调用函数print('Decorating')
时,语句f
也在运行。
这让我抓狂,我迷失在这里,因为只要功能fact
被装饰,它就会获得wrapper object
的值,当我们调用fact(6)
时,它实际上正在调用{ {1}},进一步在其内部wrapper(6)
函数正在调用函数对象wrapper
,这实际上是原始的f
,令人困惑的部分是对{的调用的方式和原因{ {1}}正在将控件发送回fact
函数以及每次打印print语句的原因,因为f(*args)
来自封闭范围,并应保留其值,因为python创建了一个闭包它
第二件事,我尝试调试代码,一旦n的值达到0,它就会将值1返回到wrapper
,然后无处不在f
再次变为1,它会在下面抛出异常线
res
任何人都可以请解释这里到底发生了什么,以及我在概念上究竟错过了什么!!!
答案 0 :(得分:3)
将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