在Python中实现事件处理程序

时间:2019-04-27 10:45:56

标签: python event-handling

我正在寻找一种方法来实现具有可重写事件处理程序的对象。

这是我要调整以使其正常工作的无效代码:

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引用?

2 个答案:

答案 0 :(得分:1)

我建议采用这种方法:您直接拥有一个属性(在本例中为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

在我看来,这极大地减少了类的代码(您定义了更少的方法)并且易于理解。这样对您有用吗?

答案 1 :(得分:0)

关键是在新分配中使用类名而不是对象

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