Python 捕捉信号瓶蓝图

Python 捕捉信号瓶蓝图,python,signals,flask,Python,Signals,Flask,我正忙于在flask中编写RESTful API,使用flask视图驱动API。由于应用程序是相当大的,所以我将代码模块化为蓝图。我在试图捕捉蓝图中的信号时遇到了一些麻烦。我可以很高兴地在我的主\uuu init\uuuu.py文件中编写“connect signal”代码,但我希望在相关蓝图中编写信号侦听器,以免主create\u app方法与蓝图特定的代码混杂在一起 目前我有这个[简化的]工作代码: def create_app(debug=False): app = Flask(_

我正忙于在flask中编写RESTful API,使用flask视图驱动API。由于应用程序是相当大的,所以我将代码模块化为蓝图。我在试图捕捉蓝图中的信号时遇到了一些麻烦。我可以很高兴地在我的主
\uuu init\uuuu.py
文件中编写“connect signal”代码,但我希望在相关蓝图中编写信号侦听器,以免主
create\u 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"

我想将信号连接代码移到我的蓝图中,但找不到一种优雅的方法。如何实现这一点?

请记住Python中的decorator语法是sugar:

@decorator
def decorated():
    pass
相当于:

def decorated():
    pass

decorated = decorator(decorated)
因此,您可以在蓝图中定义
print\u 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'])

connect\u-via(当前的应用程序)
有效吗?唉,不行。我认为这是因为从未调用过该方法。您建议我导入blueprint以及与blueprint存储在同一文件中的函数。理想情况下,我希望避免单独导入,因为每次添加连接器时都需要更改init.py。我能不能在注册蓝图时不加载连接器?@Gevious-我已经用一个示例更新了我的答案,说明了如何使用蓝图加载连接器-如果有任何不清楚的地方,请告诉我!谢谢我喜欢改变蓝图加载器的解决方案。除了最后一行中的“信号”是一个字符串而不是函数外,该函数大部分工作正常。我使用import_string根据字符串导入实际信号,这一切都很好