在学习python的过程中按照网上教程的例子写一个装饰器(原文https://www.liaoxuefeng.com/wiki/1016959663602400/1017451662295584#0),运行时报错TypeError: 'NoneType' object is not callable'
代码如下:
1 def log(func) : 2 def wrapper(): 3 print('time:') 4 func() 5 return wrapper() 6 @log 7 def show(): 8 print('2019') 9 show()
正常的运行结果应该是:
time:
2019
网上搜了一圈都说解决方法是去掉最后函数调用语句的“()”,也没有其他的说法。但感觉很有问题,所以做个笔记记录一下。
去掉后发现错误确实没有了,可以正常显示结果。但这种操作明显与我们写代码的基本常识相违背。(出特殊语法外,一般没有只通过函数名直接调用函数的)
其实从报错信息我们就可以猜到是show函数无法被调用,用代码测试了一下发现确实show变成了一个None类型
def log(func) : def wrapper(): print('time:') func() return wrapper() @log def show(): print('2019') if show is None: print("True")
运行结果:
time: 2019 True
测试后我们发现不仅show已经变成一个None类型,而且调用show的操作就已经被执行了, 实际上根据教程中的写法在 “@log”语句就已经完成了函数的调用,不用再调用一遍,最后一行代码实际上是多余的。而且这“@log”种写法将show这个函数的类型也改变了,原文是“
把@log
放到show()
函数的定义处,相当于执行了语句:
show= log(show)
”后面也无法按照常用方式对这个函数进行调用。具体的机制我暂时还不了解。或者有什么其他的方法来进行重复调用。待以后补充。
文中如有任何表述或者概念有误,欢迎回复指正!