我为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
对于应用程序中的大多数页面,用户需要同时登录和注册,因此视图处理程序使用两个装饰器。例如,
@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
然后它可以在视图处理程序上单独使用,如下所示:
@app.route(some_page)
@registration_required
def some_page_view():
# whatever code here
然而,当我尝试时,我收到错误AttributeError: 'Response' object has no attribute '__name__'
。在Flask中装饰装饰器有什么特别之处吗?
答案 0 :(得分:1)
最简单的方法是简单地调用要包装在要返回的包装器上的装饰器:
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))