Python でイベントに反応する一般的な方法を知りたいだけです。コールバック関数、デリゲート、リスナー構造など、他の言語にはいくつかの方法があります。一般的な方法はありますか?どのデフォルト言語コンセプトまたは追加モジュールがあり、どれを推奨できますか?
8 に答える
個人的には、コールバック、リスナー、デリゲートの違いはわかりません。
オブザーバーパターン(別名リスナー、別名「複数のコールバック」)は、実装が簡単です。オブザーバーのリストを保持し、そこから呼び出し可能オブジェクトを追加または削除するだけです。これらの呼び出し可能オブジェクトは、関数、バインドされたメソッド、または__call__
マジックメソッドを持つクラスにすることができます。あなたがしなければならないのは、あなたがこれらから期待するインターフェースを定義することです-例えば、それらはどんなパラメータも受け取りますか?
class Foo(object):
def __init__(self):
self._bar_observers = []
def add_bar_observer(self, observer):
self._bar_observers.append(observer)
def notify_bar(self, param):
for observer in self._bar_observers:
observer(param)
def observer(param):
print "observer(%s)" % param
class Baz(object):
def observer(self, param):
print "Baz.observer(%s)" % param
class CallableClass(object):
def __call__(self, param):
print "CallableClass.__call__(%s)" % param
baz = Baz()
foo = Foo()
foo.add_bar_observer(observer) # function
foo.add_bar_observer(baz.observer) # bound method
foo.add_bar_observer(CallableClass()) # callable instance
foo.notify_bar(3)
それはすべて、アプリケーションが必要とする複雑さのレベルによって異なります。単純なイベントの場合は、おそらくコールバックで十分です。より複雑なパターンと分離されたレベルについては、PyDispatcherや wxPython の pubsub など、ある種のパブリッシュ/サブスクライブ実装を使用する必要があります。
この議論も参照してください。
私が使用した Python ライブラリのほとんどは、イベント通知用のコールバック モデルを実装しています。これは言語にかなり適していると思います。 Pygtkは、コールバックベースのシグナル処理を実装するGObjectからすべてのオブジェクトを派生させることによってこれを行います。(ただし、これは基礎となる C GTK 実装の機能であり、言語に触発されたものではありません。) ただし、Pygtkmvcは、Pygtk の上にオブザーバー パターン (および MVC) を実装するという興味深い仕事をします。非常に華やかなメタクラス ベースの実装を使用していますが、ほとんどの場合、かなりうまく機能することがわかりました。これが行われた 1 つの方法に興味がある場合は、このコードもかなり簡単に理解できます。
このmatplotlib.cbook
モジュールにはCallbackRegistry
、確認したいクラスが含まれています。ドキュメントから:
一連の信号の登録と切断を処理し、 コールバック: シグナル='食べる'、'飲む'、'陽気になる' def oneat(x): 印刷'食べる'、x def ondrink(x): 印刷'飲み物'、x callbacks = CallbackRegistry(signals) ideat = callbacks.connect('eat'、oneat) iddrink = callbacks.connect('drink'、ondrink) #tmp = callbacks.connect('drunk'、ondrink)#これによりValueErrorが発生します callbacks.process('drink'、123)#oneatを呼び出します callbacks.process('eat'、456)#ondrinkを呼び出します callbacks.process('be merry'、456)#何も呼び出されません callbacks.disconnect(ideat)#oneatを切断します callbacks.process('eat'、456)#何も呼び出されません
おそらく、matplotlibパッケージへの依存関係は必要ありません。クラスをソースコードから独自のモジュールにコピーして貼り付けることをお勧めします。
個人的には、コールバックが使用されているのを見たことがあります。ただし、イベント駆動型の Python コードはそれほど多くないので、YMMV.
リスナーとコールバックが使用されているのを見てきました。しかし、私の知る限り、Python の方法はありません。問題のアプリケーションが適切である場合、それらは等しく実現可能であるはずです。