首页 > 技术文章 > python使用装饰器,报错TypeError: 'NoneType' object is not callable'

derekzhou 2019-08-30 16:28 原文

  在学习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)

”后面也无法按照常用方式对这个函数进行调用。具体的机制我暂时还不了解。或者有什么其他的方法来进行重复调用。待以后补充。

 

文中如有任何表述或者概念有误,欢迎回复指正!

 

推荐阅读