2011-05-27 5 views
2

私は最初のPythonプロジェクトに取り組んでいます。クラスにはすでにイベントがありません。おそらくPythonでイベントと呼ばれることはありませんが、関数参照を追加できるクラスにクラスを作成したいと考えています。私のクラスのある時点で、私のグループのすべての関数参照が実行されます。Pythonクラスは他の言語のようなイベントをサポートしますか?

これはPythonに組み込まれていますか? (私は現時点で2.7を使用しています)

+0

イベントの意味を説明してください。例外(さまざまな名前と目的)がありますが、実際にはイベントではありません。あなたが "onClick"や "onKeyDown"のようなものを参照しているのであれば、組み込みのTkinterライブラリや、Pythonで書かれた他のGUIライブラリから取得できます(私が知る限り、非GUIプログラムを使用して)。あなたはどんな行動を求めていますか? –

+0

おそらく、 "python observer pattern"を検索するべきです。このテーマには多くの記事があります。 – tkerwin

+0

もちろん実装することができます。もちろん、ドメイン固有の可能性が高いため、stdlibによって特定のニーズが満たされているわけではありません。これは 'self.events [eventtype] .add(ハンドラ)'と 'self.events [eventtype]:ハンドラ(ハンドラ)のハンドラ 'と同じくらい簡単かもしれませんし、必要に応じてもっと多くの簿記を必要とするかもしれません。詳細を与える。 – delnan

答えて

8

Pythonにはイベントシステムが組み込まれていませんが、かなり簡単に実装できます。例:

class ObjectWithEvents(object): 
    callbacks = None 

    def on(self, event_name, callback): 
     if self.callbacks is None: 
      self.callbacks = {} 

     if event_name not in self.callbacks: 
      self.callbacks[event_name] = [callback] 
     else: 
      self.callbacks[event_name].append(callback) 

    def trigger(self, event_name): 
     if self.callbacks is not None and event_name in self.callbacks: 
      for callback in self.callbacks[event_name]: 
       callback(self) 

class MyClass(ObjectWithEvents): 
    def __init__(self, contents): 
     self.contents = contents 

    def __str__(self): 
     return "MyClass containing " + repr(self.contents) 

def echo(value): # because "print" isn't a function... 
    print value 

o = MyClass("hello world") 
o.on("example_event", echo) 
o.on("example_event", echo) 
o.trigger("example_event") # prints "MyClass containing \"Hello World\"" twice 
+2

しかし3つのメモ:(1) '__init__'に' self.callbacks = {} 'を設定し、(特に貧弱な愚か者がそれを上書きするかもしれないので)偽のクラス変数を避ける方が良いでしょう。 (2)同じように、 'self.callbacks'はプライベートでなければなりません。' self._callbacks'です。 (3) 'collections.defaultdict(list)'は、与えられたイベント名に対してすでにコールバックがあるかどうかを区別する必要がないので、ハンドラの追加を簡単にします。 – delnan

+0

一般的に私は同意します。私はこの方法を使いました。なぜなら、言語にあまり慣れていない人々の便宜のために、これは最も自己完結型だったからです(私が '__init__'を使った場合、ユーザーは' super ) ')。 –

関連する問題