2012-04-13 64 views
1

我有班级的窗口。这个类有方法的onClick它获取参数控制的ID,该窗口上点击(我不能改变它的工作方式):我要让装饰这将增加我的方法回调栈是否有可能在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)中,有两种方法可以做到这一点:您可以使用metclass或类装饰器。但我不认为类装饰器可用于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) 

现在你可以从你的方法里面,叫 self.callback_stack[controlID]检索注册的功能 (OU得到他们的职能不与上面的代码中的方法,所以通过 “自我”明确地向他们)。

+0

我试着让它与类。我很惊讶,但类装饰工程在我的python2.4(在xbmc中构建的那个) – Pol 2012-04-13 16:53:48

+0

但你的方式更先进。我会尽量通过元类来指出我的意思。非常感谢你的配合。为我理解元类将是一个好的开始。 – Pol 2012-04-13 16:57:26

相关问题