装饰器为什么要有闭包?
不使用闭包装饰器也同样可以实现
def tt(func):
print("正在装饰")
return func
@tt
def test():
print("模块名{}".format(__name__))
test()
如上所示,可以在调用函数前进行装饰,无法对调用函数后装饰
为了解决在调用函数后同样可以输出装饰内容,所以选择使用闭包
def tt(func):
def wrap():
print("正在装饰")
func()
print("装饰后 ")
return wrap
@tt
def test():
print("模块名{}".format(__name__))
test()
装饰器一定返回一个函数饮用,否则报错,因为我们在调用函数时,如果装饰器返回的不是函数饮用,无法进行调用
TypeError: 'int' object is not callable
函数装饰器的种类:简单装饰,带有参数的函数装饰,装饰器带有参数
1 简单装饰,如上说明闭包问题时的代码所示,即是简单调用
2 带有参数的函数装饰,装饰器最外层参数是func,内层参数可以是固定写法
def tt(func):
def wrap(*args,**kwargs):
print("正在装饰")
func(*args,**kwargs)
print("装饰后 ")
return wrap
@tt
def test(*args,**kwargs):
print("模块名{}".format(__name__))
print(kwargs)
test(a="在装饰器里")
3 装饰器自身有参数
def tt(name):
print(name)
def aa(func):
def wrap(*args,**kwargs):
print("正在装饰")
func(*args,**kwargs)
print("装饰后 ")
return wrap
return aa
@tt("东邪")
def test(*args,**kwargs):
print("模块名{}".format(__name__))
print(kwargs)
test(a="在装饰器里")