7

API を駆動するためにフラスコ ビューを使用してフラスコで RESTful 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 に移動したいのですが、それをエレガントに行う方法が見つかりません。どうすればこれを機能させることができますか?

4

1 に答える 1

5

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'])
于 2013-04-23T11:22:10.840 に答える