有可能在python(2.4)中制作这种装饰器吗?

时间:2012-04-13 15:14:28

标签: python

我有班级窗口。这个类有方法onClick,它获取参数是在该窗口上点击的控件的id(我不能改变它的工作方式):

 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访问课程 Self不会传递给该方法。所以我可以假设它可以访问类,但无法弄清楚如何。

1 个答案:

答案 0 :(得分:2)

处理这种情况的方法是让装饰器将装饰的方法添加到数据结构(在你的情况下是CallbackStack) - 但是要将该数据结构附加到类,你需要在类时采取一些动作是创建(即解析) - 因为在解析时,装饰器,如你所说,无法访问实例或类。

在现代Python(甚至是Python 2)中,有两种方法可以做到这一点:你可以使用元类或类装饰器。但我不认为类装饰器可用于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]检索已注册的函数 (你把它们作为函数而不是上面代码的方法,所以传递 “自我”明确地告诉他们。)