我正在寻找如何实现具有可重写事件处理程序的对象的方法。
这是一个非工作代码,我想对其进行调整以使其正常工作:
class Button(object):
def __init__(self, id):
self.id = id
pass
def trigger_on_press(self):
self.on_press()
def trigger_on_release(self):
self.on_release()
def on_press(self):
# empty handler
print("Just an empty on_press handler from id=%s" % self.id)
pass
def on_release(self):
# empty handler
print("Just an empty on_release handler from id=%s" % self.id)
pass
btn = Button("btn")
btn.trigger_on_press()
def custom_handler(self):
print("Event from id=%s" % self.id)
btn.on_press = custom_handler
btn.trigger_on_press()
如何覆盖该特定实例的默认空on_press方法,以便正确传递self
引用?
我会建议这样的方法:你直接有一个属性(在本例中func_on_press
(保存对函数(而不是方法(的引用。该函数接收一个参数,该参数将成为对象(我将其称为obj
而不是self
以明确它是一个函数(。
def default_empty_event_handler(obj):
print('empty handler for id={}'.format(obj.the_id))
class Button:
def __init__(self, the_id):
self.the_id = the_id
self.func_on_press = default_empty_event_handler
self.func_on_release = default_empty_event_handler
def trigger_on_press(self):
self.func_on_press(self) # we pass 'self' as argument to the function
def trigger_on_release(self):
self.func_on_release(self) # we pass 'self' as argument to the function
现在,您可以随时更改该属性:
btn = Button('btn')
print('first trigger')
btn.trigger_on_press()
def custom_handler(obj):
print('custom handler for id={}'.format(obj.the_id))
btn.func_on_press = custom_handler
print('second trigger')
btn.trigger_on_press()
这将给出以下输出:
first trigger
empty handler for id=btn
second trigger
custom handler for id=btn
在我看来,这大大减少了类的代码(您定义的方法更少(,并且易于理解。这对你有用吗?
关键是在新的赋值中使用类名而不是对象
将btn.on_press = custom_handler
更改为Button.on_press = custom_handler
,神奇地起作用
解释:
当你调用btn.on_press()
时,它将被转换为它的原始调用'Button.on_press(btn(',所以你需要改变蓝图中的调用而不是对象
您的示例:
class Button(object):
def __init__(self, id):
self.id = id
pass
def trigger_on_press(self):
self.on_press()
def trigger_on_release(self):
self.on_release()
def on_press(self):
# empty handler
print("Just an empty on_press handler from id=%s" % self.id)
pass
def on_release(self):
# empty handler
print("Just an empty on_release handler from id=%s" % self.id)
pass
btn = Button("btn")
btn.trigger_on_press()
def custom_handler(self):
print("Event from id=%s" % self.id)
Button.on_press = custom_handler # here use the class name not obj name
btn.trigger_on_press()
输出:
Just an empty on_press handler from id=btn
Event from id=btn