【问题标题】:Catch signals in Flask Blueprint在 Flask 蓝图中捕获信号
【发布时间】:2013-04-16 07:13:37
【问题描述】:

我正忙着在烧瓶中编写一个 RESTful API,使用烧瓶视图来驱动 API。由于应用程序相当大,我将代码模块化为蓝图。尝试在蓝图中捕获信号时遇到了一些麻烦。我可以愉快地在我的主 __init__.py 文件中编写“连接信号”代码,但我想在相关蓝图中编写信号侦听器,以免主 create_app 方法与蓝图特定代码混淆。

目前我有这个[简化的]工作代码:

def create_app(debug=False):
    app = Flask(__name__)
    ...
    app.register_blueprint(my_blueprint)
    @mysignal.connect_via(app)
    def print_howdy(sender, **extra):
       print "howdy"

我想将信号连接代码移到 my_blueprint 中,但找不到优雅的方法。我怎样才能做到这一点?

【问题讨论】:

  • connect_via(current_app) 工作吗?
  • 唉,它没有。我认为这是因为该方法从未被调用过。

标签: python signals flask


【解决方案1】:

请记住 Python 中的装饰器语法是糖:

@decorator
def decorated():
    pass

相当于:

def decorated():
    pass

decorated = decorator(decorated)

因此,您可以在蓝图中定义print_howdy 并将其与您的蓝图一起导入。为了保持干净,您甚至可以在蓝图中定义一个信号侦听器列表,并一次性将它们全部导入:

mysignal.connect_via(app)(print_howdy)

甚至:

# blueprint.py
def print_howdy(): pass
def print_seeya(): pass

MYSIGNAL_LISTENERS = (print_howdy, print_seeya)

# __init__.py
from blueprint import MYSIGNAL_LISTENERS
for listener in MYSIGNAL_LISTENERS:
    mysignal.connect_via(app)(listener)

您甚至可以将此模式抽象为一个函数:

from werkzeug.utils import import_string

DEFAULT_SIGNALS = ('MYSIGNAL', 'MYOTHERSIGNAL')

def register_blueprint_and_signals(app, bp_path, signals=DEFAULT_SIGNALS):
    bp = import_string(bp_path)
    app.register_blueprint(bp)


    signal_path = bp_path.rsplit(".", 1)[0] + "."
    for signal in signals:
        try:
            listeners = import_string(signal_path + signal + '_LISTENERS')
        except ImportError:
            continue

        for listener in listeners:
            signal.connect_via(app)(listener)

然后你可以像这样使用它:

app = Flask(__name__)
register_blueprint_and_signals(app, "my_module.my_blueprint")
register_blueprint_and_signals(app, "another.blueprint", ['ANOTHERSIGNAL'])

【讨论】:

  • 您是在建议我导入蓝图以及与蓝图存储在同一文件中的函数。理想情况下,我希望避免单独导入,因为这需要我在每次添加连接器时更改 init.py。蓝图注册后,我不能以某种方式加载连接器吗?
  • @Gevious - 我已经更新了我的答案,举例说明了如何使用蓝图加载连接器 - 如果有任何不清楚的地方,请告诉我!
  • 谢谢。我喜欢更改蓝图加载器的解决方案。该函数大部分工作,除了最后一行中的“信号”是一个字符串而不是一个函数。我使用 import_string 根据字符串导入实际信号,一切正常
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-14
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多