自动发现python装饰程序

自动发现python装饰程序,python,decorator,faust,Python,Decorator,Faust,我想知道是否有一个标准化的方法或最佳实践来扫描/自动发现装饰器,就像在Django、Flask等其他一些LIB中一样。通常,装饰器在调用内部函数时提供额外的/包装的功能 在下面所示的示例中,也是在Flask/Django(路由装饰器)中,装饰器更常用于添加总体功能,例如,最初在装饰器逻辑中生成tcp客户端,然后在收到消息时调用内部func来处理它 Flask/Django注册一个url路由,其中只有在请求url时才调用内部func。所有示例都需要装饰器逻辑的初始注册(扫描/发现),以便初始启动总

我想知道是否有一个标准化的方法或最佳实践来扫描/自动发现装饰器,就像在Django、Flask等其他一些LIB中一样。通常,装饰器在调用内部函数时提供额外的/包装的功能

在下面所示的示例中,也是在Flask/Django(路由装饰器)中,装饰器更常用于添加总体功能,例如,最初在装饰器逻辑中生成tcp客户端,然后在收到消息时调用内部func来处理它

Flask/Django注册一个url路由,其中只有在请求url时才调用内部func。所有示例都需要装饰器逻辑的初始注册(扫描/发现),以便初始启动总体功能。对我来说,这似乎是装饰师的另一种用法,如果有,我想了解最佳实践方法

请参见下面的示例,其中decorator app.agent()会在asyncio事件循环中自动触发侦听(kafka流)客户端,然后内部函数hello()会在稍后处理传入的消息,仅当接收到消息时,需要在脚本开始时首先对相关的装饰器逻辑进行初始检查/扫描/发现

import faust

class Greeting(faust.Record):
    from_name: str
    to_name: str

app = faust.App('hello-app', broker='kafka://localhost')
topic = app.topic('hello-topic', value_type=Greeting)

@app.agent(topic)
async def hello(greetings):
    async for greeting in greetings:
        print(f'Hello from {greeting.from_name} to {greeting.to_name}')

@app.timer(interval=1.0)
async def example_sender(app):
    await hello.send(
        value=Greeting(from_name='Faust', to_name='you'),
    )

if __name__ == '__main__':
    app.main()
没有什么是“发现的”。当您从包中导入模块时,所有代码都将执行。这就是为什么我们有
if uuuu name_uuu=='\uuuu main\uuuu'
来停止导入时执行的某些代码。当您运行代码时,将“发现”装饰程序

我认为
烧瓶蓝图
就是一个很好的例子。您可以看到在导入模块时它是如何注册url端点的。它所做的只是在列表中添加:

    def route(self, rule, **options):
        """Like :meth:`Flask.route` but for a blueprint.  The endpoint for the
        :func:`url_for` function is prefixed with the name of the blueprint.
        """
        def decorator(f):
            endpoint = options.pop("endpoint", f.__name__)
            self.add_url_rule(rule, endpoint, f, **options)
            return f
        return decorator

代码运行时,将对装饰器进行评估,它们只需要保留一些它们装饰的所有函数的内部列表。这些都存储在对象中。

欢迎提供任何更新此问题的提示,因为我假设我只是在这里搜索错误的关键字。.我对decorator的知识不太了解,但我不明白“discover”是什么意思。app.main()正在收集/发现/搜索所有decorator以提供附加功能。Flask正在做一些非常类似的事情,请参见这里的第一个代码示例:耶!浮士德用“金星人”来寻找装饰师。这实际上会递归地导入包目录中的所有模块。我不太喜欢这种方法,但它很方便。需要注意的是,它可以很容易地导入一些不应该导入的内容,例如测试模块或不打算导入的脚本。Django使用了一种不同的方法,在这里您明确列出了已安装的应用程序,它会在这些已安装的应用程序中搜索“admin.py”模块。@asksol您是最好的,谢谢!谢谢根据您的示例,代码将在导入时运行,以添加端点规则,但也会启动内部函数,我猜这不是预期的结果。请看以及-经过进一步的搜索,我发现(注意在浮士德报告)。我想这就是我要找的。然而,这似乎很复杂。@trbck我认为您需要更清楚地了解您的预期行为。你的第一个链接和我挖掘出来的没有什么不同。如果你没有更多的背景,其他的对我来说似乎毫无意义。你确定你需要更复杂的东西吗?或者你已经确定了一些你甚至不需要的想法吗?同意,谢谢。通常,当调用内部func时,装饰器提供额外的/包装的功能。在所有提到的示例中,装饰器都是用来添加总体功能的,例如faust最初生成一个kafka streams侦听器,然后在收到消息时调用内部func。Flask/Django注册url路由,然后只有在请求url时才调用内部func。所有示例都需要初始注册(discover)来初始启动总体功能。在我看来,这似乎是一个替代使用装饰。。。