blinker モジュール
Flask使い始めの頃に「before_request」やら「teardown_request」の当たりで利用されているのを見て「なんだこれ?」って思って、そのまま放置してたやつ。
Blinker: Blinker Documentation
簡単に言うとオブジェクトの間のシグナルの送信/受信の仕組みを提供してくれるっぽい。簡単な使い方を紹介する。
インストール
pip install blinker
簡単な使い方
下記のようなコードを例にしましょう。
#!/usr/bin/env python #-*- coding:utf8 -*- from blinker import signal class Person(object): def __init__(self, name): self.name = name def __repr__(self): return self.name def say_my_name(lover): print "Hello! my name is %s." % lover def drillbits(lover): print "drillbits love %s !!!!" % lover def oyakata(lover): print "oyakata love %s !!!!" % lover #create person object podhmo = Person('podhomo') pasberth = Person('pasberth') tell_k = Person('tell-k') #create signal mysignal = signal('love') #connect mysignal.connect(say_my_name) #send signal mysignal.send(pasberth) mysignal.send(podhmo) mysignal.send(tell_k)
やっている事はこんな感じです。
- (create signal) signal関数で名前付きのsignalを作る
- (connect) connect関数で、シグナルを送信したときに実行される関数を登録
- (send signal) シグナルを送信する、send関数の引数は、connectで登録した関数の引数としてわたされる。
これを実行するとこんな、三つのPersonオブジェクトが自己紹介をします。
Hello! my name is pasberth. Hello! my name is podhomo. Hello! my name is tell-k.
シグナルに登録(connect)できる関数は同じ引数であれば複数登録する事も可能です。またconnect関数にsender引数を渡すことで、シグナル送信されたオブジェクトによって、関数の呼び分けすることもできます。
たとえば上のコードをこんな風にしてみましょう。
#connect mysignal.connect(say_my_name) mysignal.connect(drillbits, sender=pasberth) mysignal.connect(oyakata, sender=podhmo)
このようにsenderを設定すると下記のようになります。
- say_my_name は シグナル送信の全てで実行される。
- drillbits 関数 は シグナル送信時の引数がpasberthでないと実行されない。(drillbitsはpasberthにしか興味がない)
- oyakata 関数 は シグナル送信時の引数がpodhmoでないと実行されない。(oyakataはpodhmoにしか興味がない)
実行結果はこの通りです
Hello! my name is pasberth. drillbits love pasberth !!!! Hello! my name is podhomo. oyakata love podhomo !!!! Hello! my name is tell-k.
基本的に実行順序はconnectされた順となります。あまり普段はお世話になる機会はそれほどなさそうですが、ドキュメントにはもう少しくわしく利用方法も書いてあるので、暇があったら、また調べてみたいと思います。
余談
- なおこの記事に登場する、変数名および、関数名、クラス名などは作者の想像上のものであり、実在する人物・団体とは一切関係はございません。フィクションです。フィクション。