1

我有课窗口。此类具有 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 获得对类的访问权限,而不是传递给该方法。所以我可以假设它可以访问课程,但无法弄清楚如何。

4

1 回答 1

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]以检索已注册的函数(您可以将它们作为函数而不是使用上面的代码的方法获取,因此将“self”显式传递给它们)。

于 2012-04-13T16:08:03.440 回答