2014-12-03 7 views
1

я написал два декораторов для моего приложения Колбы 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

Вы действительно хотите украсить декораторов или не вы, а хотите украсить декорированные функции? Разумеется, разница имеет значение. – Alfe

+0

И, пожалуйста, исправьте отпечаток кода, который вы опубликовали. – Alfe

+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)) 
Смежные вопросы