一、基本装饰器 (@f)
def f1(h1):
def f2(args_of_h1):
print('previous')
h1(args_of_h1)
print('after')
return f2
@f1
def h1(args_of_h1):
print(args_of_h1)
h1('this is h1')
结果:
previous
this is h1
after
注意看
1、f1
的参数是所装饰的函数的函数名(h1)
2、f2
的参数是f1
所装饰的函数(h1)
的参数
3、return f2
是f1
的返回值,返回类型是函数类型
所以说:我执行h1
的时候实际上执行的是f2
当我们把 h1(args_of_h1)
注释掉,即
#h1(args_of_h1)
执行结果为:
previous
after
上面的f1
具有的缺陷:
1、只能装饰含有一个参数的函数
所以通常装饰器会写成
def f1(h):
def f2(*args,**kwargs):
print('previous')
h(*args,**kwargs)
print('after')
return f2
@f1
def h1(args_of_h1):
print(args_of_h1)
(*args,**kwargs)
*
表示可以接受多个参数
**
表示可以接受多个键值对参数
示例
('v1','v2',10,k1='n1',k2=9)
*args
将被包装成tuple
,**kwargs
将被包装成dict
二、带参数的装饰器(@f(*arg,**kwargs))
def f(*arg,**kwarg):
def f1(h):
def f2(*args,**kwargs):
print('previous')
h(*args,**kwargs)
print('after')
print(arg)
return f2
return f1
@f('this is f')
def h1(args_of_h1):
print(args_of_h1)
结果:
previous
this is h1
after
('this is f',)
对比一中的代码块,上面代码块增加了一层装饰器使得我可以在@f()
中添加参数
注意缩进
,我们必须返回一个可调用的函数,这里我们返回f1
,f1
又返回f2
,所以最终执行的是f2
,最终执行的 f2 始终是 f1 的返回值,f1 以被装饰函数 h 作为参数
三、类包装的装饰器(@app.route(''/))
由上面可知,要使用装饰器装饰一个函数,条件:
1、一个装饰器函数必定返回一个可调用(可使用的函数)
2、只要在一个被装饰函数上使用@decorator(args)
即可
那么我的这个decorator函数
也可在一个类中
所以app
是一个Flask
类的对象,route
是在Flask
类中定义的装饰器函数
下面是一个简单实现,不涉及路由
class Flask():
def __init__(self):
pass
def f2(self,f):
def f3(*args):
print('start')
f()
print(args[0:])
print('end')
return f3
app = Flask()
@app.f2
def hello(*args):
print("this is hello")
hello('args of hello')
结果:
start
this is hello
('args of hello',)
end