1.解释
装饰器的功能就是对一个已有的函数进行包装,在不改变其内部代码的情况下,将其他的功能动态地加载进去。
例如如下的函数
def aaa():
print("Original")
def msg(aaa)
this_is = "example"
def haha():
if this_is == "example":
print("HIHI")
aaa()
return haha
aaa = msg(aaa)
这里aaa函数是一个已有的而函数,我们想在不改变它内部代码的情况下,创造一个给它新加入打印“HIHI”的功能,就可以通过一个函数生成器(msg函数),来返回一个函数,这个函数接受aaa作为参数,把它当做局部函数hahah的内部调用,然后把haha函数返回,再把函数名重定向到返回的haha函数上。这样的新的aaa函数的实际内容就变成了
this_is = "example"
if this_is == "example":
print("HIHI")
print("Original")
且在这种模式下,我们没有加入在aaa中加入额外代码,这对于在不改变函数内容的情形下新加内容、组合已有的功能动态生成新功能都非常有效。
2. 语法糖
python中的@操作符就是装饰器的语法糖,用以简化最后的赋值操作。
就是说
@a1
def b1()
的意义和
b1=a1(b1)的效果是一样的。
3.使用举例
注意,下列的deco函数中都必须定义并返回一个嵌套函数,不然在调用时会出现报错:
TypeError: 'NoneType' object is not callable
不带参数的
def deco(func):
def wrapper():
print('hi')
func()
return wrapper
@deco
def func():
print("hello")
print("world")
func()#运行
带参数:
def deco(func):
def wrapper(a,b):
func(a,b)
return wrapper
@deco
def func(a,b):
print("hello,here is a func for add :")
print("result is %d" %(a+b))
func(a,b)#使用
带不定参数:
def deco(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
return wrapper
@deco
def func(a,b):
print("hello,here is a func for add :")
print("result is %d" %(a+b))
@deco
def func2(a,b,c):
print("hello,here is a func for add :")
print("result is %d" %(a+b+c))
#运行
func(1,2)
func1(1,2,3)