python - 将装饰器应用于装饰器

标签 python google-app-engine python-2.7 flask decorator

我为我的 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/

相关文章:

python - 将不同的 URL 映射到同一 View

java - Google App Engine 的模板引擎

python - 制作 "string".functions() 函数 python

python - 如何将 backspace\x08 应用于字符串?

Python randn 和 normal 的区别

python - 如何获得加权高斯滤波器

python - Keras——使用 LSTM 层时精度较低,但不使用 LSTM 时精度很好

python - 除了Datastore之外,是否还提供Google App Engine的API来更好地配置Bigtable?

google-app-engine - 谷歌应用引擎是否支持环境变量?

Python 2.7 os.EX_SOFTWARE 未找到