不带参数的装饰器
@dec1@dec2def some(f): pass
转换为一个装饰器
方法一:
def composed(*decs): def deco(f): for dec in reversed(decs): f = dec(f) return f return deco
然后使用
@composed(dec1, dec2)def some(f): pass
方法二:
def multiple_decorators(func): return dec1(dec2(func))
然后使用
@multiple_decoratorsdef foo(): pass
方法三:
def compose(f, g): return lambda x: f(g(x))combined_decorator = compose(dec1, dec2)
然后使用
@combined_decoratordef f(): pass
带参数的装饰器合并
如:让flask 的@mod.route('/list')和@login_required合并
@mod.route('/standardization/')@login_requireddef scriptstandardization(sid): pass
定义装饰器
from flask_login import login_requireddef needloginroute(mod,url, g=login_required): return lambda x: mod.route(url)(g(x))
(支持更多参数的route)
def myroute(f,url, g=login_required, needlogin=True,**kwargs): """必须登录的装饰器 @parma f:蓝图的mod @parma url:路由url @parma g:login_required装饰器 @param needlogin: True时为需要登录(默认) """ if needlogin: return lambda x: f.route(url,**kwargs)(g(x)) else: return lambda x: f.route(url,**kwargs)(x)
然后使用
@needloginroute(mod, '/standardization/')def scriptstandardization(sid): pass
当然;mod用的是蓝图
from flask import Blueprintmod = Blueprint('script', __name__)
掌握原理即可,如a为f装饰器的参数,如b为g装饰器的参数,调用时候用compose作为装饰。
def compose(f, a, g, b): return lambda x: f(a)(g(b)(x))
备注:
合并装饰器@mod.route('/')和@login_required会导致一个问题,eclipse pydev debug模式下修改代码需要重启才能生效,解决办法,直接在mod上写before_request登录验证,这样整个view页面需要登录的话就不需要加@login_required装饰器了。
和login_required的实现原理相同:
If there are only certain times you need to require that your user is
logged in, you can do so with::if not current_user.is_authenticated:
return current_app.login_manager.unauthorized()from flask import current_appfrom flask_login import current_user@mod.before_requestdef before_request(): if not current_user.is_authenticated: return current_app.login_manager.unauthorized() # 没有认证返回login_manager.unauthorized装饰器函数的页面