2012-04-13 4 views
1

私はクラスウィンドウを持っています。このクラスは、コントロールのIDを引数を取得する方法のonClickは(私はそれが仕事だ方法を変更することはできません)、そのウィンドウをクリックした:python(2.4)でこの種のデコレータを作ることは可能でしょうか?

class Window(SoneBaseWindowClass): 

    def onClick(self,controlID): 
     print controlID 

私はコールバックスタックに私のメソッドを追加しますデコレータを作りたいです。 メソッドよりも、特定のコントロールがクリックされたときにonClickメソッドが呼び出されます。 ので:

class Window(SoneBaseWindowClass): 
    def __init__(self): 
     callback_stack = {} 

    def onClick(self,controlId): 
     callback = self.callback_stack.get(controlID) 
     if callback is not None: 
      callback() 

    # suppose to add decorated method to a callback_stack 
    def onclick_decorator(method): 
     pass 

だから私はcallback_stackにいくつかのメソッドを追加しますデコレータを作成する必要があります。を使用している例。

class MyWindow(Window): 

    @onclick_decorator(12345) 
    def someMethod(self): 
     print "Gets called when control with id 12345 clicked" 

実際の質問は、私がonclick_decorator 自己がそのメソッドに渡されていないから、クラスへのアクセスもを得ることができる方法です。だから私はクラスにアクセスすることができると仮定することができますが、どのように把握できませんでした。

答えて

2

このような状況に対処する方法は、データ構造(あなたのケースではCallbackStack)にデコレータを追加することですが、データ構造をクラスに追加するには、クラスが作成されます(つまり、解析されます)。つまり、解析されている間、デコレータは、インスタンスまたはクラスのいずれにもアクセスできません。

現代のPython(Python 2も)には、それを行うには2つの方法があります:eitehrは、メタクラスまたはクラスデコレータを使用します。しかし、私はクラスデコレータがPython 2.4で利用できるとは思っていません - あなたはメタクラスを持つ必要があります。

これは複雑ではありません。メタクラス上の__new__メソッドは、解析中に構築された辞書に渡されます。あなたのデコレータは、メタクラスが見つけることができる属性で目的のメソッドをマークし、これらのマーキングからcallback_stackを構築するだけです。 call_backスタックでも辞書になります

def on_click_decorator(key): 
    def real_decorator(func): 
     setattr(func, "_callback_to", key) 
     return func 
    return real_decorator 


class Meta(type): 
    def __new__(metacls, name, bases, dct): 
     callback_stack = {} 
     for name, value in dct.items(): 
      if hasattr(value, "_callback_to"): 
       callback_stack[value._callback_to] = key 
     dct["callback_stack"] = callback_stack 
     # we've done all needed manipulation - no 
     # need for the class to be from a special type - so we 
     # don't call type.__new__ 
     return type(name, bases, dct) 

今、あなたは、あなたの方法の中から、(OUの機能ではない、上記のコードを持つメソッドとしてそれらを取得し、その を渡す登録されている機能 を取得するために self.callback_stack[controlID]を呼び出すことができます"自己"明示的にそれらに)。

+0

私はクラスで作ろうとしました。私は驚いたが、クラスのデコレータは私のpython2.4(xbmcで構築されているもの)で動作します – Pol

+0

しかし、あなたはもっと高度です。私が指摘したように、私はメタクラスを通して作ろうとします。ありがとうございます。私がメタクラスを理解するのは良いスタートになるでしょう。 – Pol

関連する問題