我为我的 Flask GAE 应用程序编写了两个装饰器:
def login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if (not users.get_current_user()):
return redirect(home_url)
return f(*args, **kwargs)
return decorated_function
def registration_required():
@wraps(f)
def decorated_function(*args, **kwargs):
if(not is_registered_user(users.get_current_user().user_id())):
return redirect(user_reg_url)
return f(*args, **kwargs)
return decorated_function
对于应用程序中的大多数页面,用户需要登录和注册,因此 View 处理程序使用这两种装饰器。例如,
@app.route(some_page)
@login_required
@registration_required
def some_page_view():
# whatever code here
我认为从设计的角度来看,如果 registration_required
的实现本身用 login_required
修饰会更有意义,因为它需要用户登录。检查他们是否已注册。我尝试过的是这样的:
@login_required
def registration_required():
@wraps(f)
def decorated_function(*args, **kwargs):
if(not is_registered_user(users.get_current_user().user_id())):
return redirect(user_reg_url)
return f(*args, **kwargs)
return decorated_function
然后它可以在 View 处理程序上单独使用,如下所示:
@app.route(some_page)
@registration_required
def some_page_view():
# whatever code here
但是,当我尝试时,我收到错误 AttributeError: 'Response' object has no attribute '__name__'
。在 Flask 中装饰装饰器需要做一些特别的事情吗?
最佳答案
最简单的方法是简单地调用您想要包装在返回的包装器上的装饰器:
def registration_required():
@wraps(f)
def decorated_function(*args, **kwargs):
if(not is_registered_user(users.get_current_user().user_id())):
return redirect(user_reg_url)
return f(*args, **kwargs)
return login_required(decorated_function)
这是有效的,因为装饰器语法只是一种简写:
@decorator
def some_func():
pass
等同于:
def some_func():
pass
some_func = decorator(some_func)
还有:
@decorator2
@decorator1
def some_func():
pass
等同于:
def some_func():
pass
some_func = decorator2(decorator1(some_func))
关于python - 将装饰器应用于装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27280188/