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された順となります。あまり普段はお世話になる機会はそれほどなさそうですが、ドキュメントにはもう少しくわしく利用方法も書いてあるので、暇があったら、また調べてみたいと思います。

余談

  • なおこの記事に登場する、変数名および、関数名、クラス名などは作者の想像上のものであり、実在する人物・団体とは一切関係はございません。フィクションです。フィクション。