我有班级窗口。这个类有方法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不会传递给该方法。所以我可以假设它可以访问类,但无法弄清楚如何。
答案 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]
检索已注册的函数
(你把它们作为函数而不是上面代码的方法,所以传递
“自我”明确地告诉他们。)