Signalはカスタマイズして利用できるようです。
カスタマイズして使うと、Signalをより細かく設定できるようになるみたいだね
flaskのSignalの勉強を続けています。前回は、Signalの具体的な使い方をプログラムで確認してみました。引き続きチュートリアルを進めていきたいと思います。
正直なところ、具体的な例で示された使い方しかまだよくわかっていないのですが^^;おそらくゴリゴリに使い始めると、「こんな機能欲しいな→Signal使える!」みたいな流れになるレベルの機能のような気がしています。
進めいているチュートリアルはこちらになります。
こんな人の役にたつかも
・flaskチュートリアルを勉強している人
・flaskのSignalについて勉強している人
カスタマイズしたSignal
Signalの作成
Signalにオリジナルの名前をつけて作成するときには、次のようにします。
#SignalはBlinkerモジュールで作成します。
from blinker import Namespace
my_signals = Namespace()
#利用時には、次のように名称をつけて作成します。
model_saved = my_signals.signal('model-saved')
blinkerモジュールのNamespaceを利用すると、Signalに名前がつけられるようです。今回は、「model_saved」という名前のsignalを作成しました。
Signalの送信
チュートリアルでは、sendをすればsignalが送信されます、みたいな軽い流れで書いてあるのです・・・しかし、ここが全くよくわかりませんでした( ´∵`)とりあえず、次のようなプログラムが記載されています。
class Model(object):
...
def save(self):
model_saved.send(self)
いきなりModelクラスが出てきました。おそらく、何かしらのクラスの中で先ほどのSignalオブジェクトからsendをしてね、というようなことだと思います。また、sendメソッドでは、最初の引数がsignalの送信者になるそうで、このようにクラス内で利用する場合は、selfのようにして、送信者を渡します。
ちなみに、sendをflaskのコンテキスト中で利用するときは、「current_app._get_current_object()」のように指定することができるようです。「current_app」はproxyで実態が「_get_current_object()」で取得できるようで、このような書き方になっているみたいです。
う〜ん、全然よくわかりません 笑
blinkerのドキュメントも読んだsignalのプログラム例
flaskチュートリアルのSignalが、結局は送信しているのみで、何をどうしたいのかいまいち理解できませんでしたので、少しだけblinkerのドキュメントもかじってみることにしました。
そこで作成したテストプログラムが次のプログラムになります。
以前作成したミニマムなアプリのtestsフォルダに「test_signal.py」として以下のプログラムを追加しました。
import min_app
from blinker import Namespace
#Signalを送信したときに呼ぶ関数
def say_hello(sender):
print("Hello")
#カスタマイズしたSignalを呼び出すテスト
def test_my_signal():
#Signalに名前をつける流れです。
my_signals = Namespace()
model_saved = my_signals.signal('model-saved')
#シグナルにsay_helloをconnectしました。
model_saved.connect(say_hello)
#min_appをsenderとしてsignalをsay_helloに送信します。
model_saved.send(min_app.app)
#テストが失敗するようにして経過を確認できるようにしています。
assert 0 == 1
どうやら、connectでsignalによって何が実行されるのか、通知される側の機能を定義して紐づけるようです。そして、sendによってその関数が実行されるような仕組みのようです。
動作させるための環境構築
このプログラムが動作するflaskのプロジェクトをGitHubの「panda-flaskリポジトリ:sognal_testブランチ」にてcloneができますので、動作を試してみたい方は、git clone してみてくださいね!
$ git clone -b signal_test https://github.com/perfectpanda-works/panda-flask.git
git cloneしたら、panda-flaskフォルダの階層内で次のようにPython仮想環境venvを作成し、Pythonモジュールをインストールします。
mac
$Python3 -m venv venv
$. venv/bin/activate
(venv)$ pip install -r requirements.txt
windows
>py -3 -m venv venv
>venv¥Scripts¥activate
(venv)> pip install -r requirements.txt
そして、pytestを行います。
$ pytest
Signalに接続したsay_helloが実行されています。
とりあえず、この挙動を足がかりに、必要になったときに色々といじっていきたいと思います。