如何在 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 中对装饰器进行分组的主要内容,如果未能解决你的问题,请参考以下文章

python 中对redis 操作采用装饰器进行处理,怎么做

python中对变量的作用域LEGB闭包装饰器基本理解

python_如何在类中定义装饰器

python函数作用域+装饰器

python进阶之装饰器之2.定义一个可接受参数的装饰器如何定义一个属性可由用户修改的装饰器定义一个能接受可选参数的装饰器

Python之简单理解装饰器