1. 视图加装饰器
1.1 装饰器的位置
见如下代码
from flask import Flask
app = Flask(__name__)
def wrapper(func):
def inner(*args,**kwargs):
print('beforeFunc')
ret = func(*args,**kwargs)
return ret
return inner
@app.route('/index')
@wrapper
def index():
return 'index页面'
if __name__ == '__main__':
app.run()
注意:
1.重点是添加的装饰器的位置,wrapper装饰器必须要在route/路由装饰器下面,这样才能保证每次访问/index路径的时候能成功执行wrapper装饰器实现的功能
2.就相当于route下面的代码段作为一个整体被route/路由装饰器装饰
3.route装饰器,装饰的函数实际上是inner函数(因为执行index函数的时候相当于把inner传入了wrapper装饰器,返回了inner),所以route实际上装饰的是后来返回的inner函数
存疑问题:
需要注意的是,由于route装饰器装饰的都是inner函数,若endpoint参数没有赋值定义别名,此时实际上对应的是函数名inner(注意,不是index而是inner);此时如果有了另一个视图函数如user函数做同样的装饰,那么再通过inner反解URL的时候,就无法确定是返回index还是user了;相当于重名了,此时Flask就无法运行
此时就需要functools.wraps
方法来解决该问题
1.2 解决inner函数名问题
from functools import wraps
如下代码
from flask import Flask
from functools import wraps
app = Flask(__name__)
def wrapper(func):
@wraps(func)
def inner(*args,**kwargs):
print('beforeFunc')
ret = func(*args,**kwargs)
return ret
return inner
@app.route('/index')
@wrapper
def index():
return 'index页面'
@app.route('/user')
@wrapper
def user():
return 'user页面'
if __name__ == '__main__':
app.run()
通过functools.wraps
装饰器,可以返回所有被装饰的视图函数本身的一些属性值(如,函数名__name__
),这样就解决了上述描述的因endpoint
参数默认值情况下,导致的反解URL的时候均是inner函数名的情况
2. 总结
- 自己定义的装饰器都要放在route/路由装饰器下面
- 通过
functools.wraps
来解决路由反解问题;一般情况下装饰器必用即可