如何在 Python 中对装饰器进行分组

Posted

技术标签:

【中文标题】如何在 Python 中对装饰器进行分组【英文标题】:How to group decorators in Python 【发布时间】:2018-03-15 19:46:09 【问题描述】:

在 Flask 中,我为每条路由使用了一组装饰器,但代码“丑陋”:

@app.route("/first")
@auth.login_required
@crossdomain(origin='*')
@nocache
def first_page:
    ....

@app.route("/second")
@auth.login_required
@crossdomain(origin='*')
@nocache
def second_page:
    ....

我希望有一个声明,用一个装饰器将所有这些分组:

@nice_decorator("/first")
def first_page:
    ....

@nice_decorator("/second")
def second_page:
    ....

我尝试按照Can I combine two decorators into a single one in Python? 的答案进行操作,但无法使其正常工作:

def composed(*decs):
    def deco(f):
        for dec in reversed(decs):
            f = dec(f)
        return f
    return deco

def nice_decorator(route):
    composed(app.route(route),
             auth.login_required,
             crossdomain(origin="*"),
             nocache)

@nice_decorator("/first")
def first_page:
    ....

因为这个我不明白的错误:

@nice_decorator("/first")
TypeError: 'NoneType' object is not callable

在其中一个 cmets 之后,我使用另一种有效但无法指定路由参数的形式对其进行了定义:

new_decorator2 = composed(app.route("/first"),
                          auth.login_required,
                          crossdomain(origin="*"),
                          nocache)

是否可以定义一个带参数的装饰器?

【问题讨论】:

nice_decorator 不返回任何内容,因此返回 NoneNone 是不可调用的。在composed(app.route...)之前添加return 【参考方案1】:

您没有正确定义构图。您需要将nice_decorator 的定义更改为:

def nice_decorator(route):
    return composed(
        app.route(route),
        auth.login_required,
        crossdomain(origin="*"),
        nocache
    )

您以前的版本实际上从未返回任何内容。 Python 不像 Ruby 或 Lisp,其中最后一个表达式是返回值。

【讨论】:

谢谢大家!我完全忘记了回报。

以上是关于如何在 Python 中对装饰器进行分组的主要内容,如果未能解决你的问题,请参考以下文章