Python装饰器修饰阶乘代码报int与NoneType*运算TypeError错误
错误产生原因
报错核心诱因是自定义的计时装饰器未透传被装饰函数的返回值,导致递归阶乘逻辑中参与乘法运算的操作数出现None,触发类型不匹配错误。
装饰器语法
@dec加在函数定义上方的本质是执行fac = dec(fac),装饰完成后全局环境中调用的fac实际是装饰器返回的内层wrap函数,而非原本实现阶乘计算的函数。
原装饰器内层wrap函数的问题代码如下:
def wrap(d): now = datetime.now() f(d) print(datetime.now() - now)
这段代码仅调用了传入的原阶乘函数,但没有通过return返回原函数的执行结果。Python语法中,没有显式写return语句的函数,默认返回值为None。
报错触发的完整逻辑链:
- 执行
fac(5)时实际进入wrap(5),内部调用原阶乘函数走到5 * fac(4)的递归分支 - 所有层级的递归调用
fac(k)实际触发的都是被装饰后的wrap(k),会逐层向内递归直到n == 1的终止条件 - 最内层调用
fac(1)时,wrap(1)内部确实执行了原阶乘逻辑拿到返回值1,但wrap本身没有返回这个值,对外输出的是默认值None - 回到上一层递归的
2 * fac(1)逻辑时,运算实际变成2 * None,Python不支持整数和NoneType做乘法运算,直接抛出对应TypeError
修复方案
修改装饰器的wrap函数,保留原函数的执行结果并在计时逻辑结束后返回,保证递归调用能拿到正确的阶乘计算值。修复后的完整代码:
from datetime import datetime def dec(f): def wrap(d): now = datetime.now() res = f(d) print(datetime.now() - now) return res return wrap @dec def fac(n): if n == 1: return n else: return n*fac(n-1) fac(5)
内容的提问来源于stack exchange,提问作者Sergey Leonov
相关产品推荐
相关产品推荐

