Python:回调,代表,......?什么是常见的?

时间:2009-01-14 17:20:29

标签: python events delegates callback

只想知道在python中对事件做出反应的常用方法是什么。在其他语言中有几种方法,如回调函数,委托,监听器结构等。 有共同的方法吗?有哪些默认语言概念或附加模块,您可以推荐哪些?

8 个答案:

答案 0 :(得分:18)

我个人认为回调,听众和代表之间没有区别。

observer pattern(a.k.a听众,a.k.a“多个回调”)很容易实现 - 只需保存一个观察者列表,并从中添加或删除callables。这些可调用对象可以是函数,绑定方法或具有__call__魔术方法的类。您所要做的就是定义您期望的界面 - 例如他们收到任何参数。

class Foo(object):
  def __init__(self):
    self._bar_observers = []

  def add_bar_observer(self, observer):
    self._bar_observers.append(observer)

  def notify_bar(self, param):
    for observer in self._bar_observers:
      observer(param)

def observer(param):
  print "observer(%s)" % param

class Baz(object):
  def observer(self, param):
    print "Baz.observer(%s)" % param

class CallableClass(object):
  def __call__(self, param):
    print "CallableClass.__call__(%s)" % param

baz = Baz()

foo = Foo()

foo.add_bar_observer(observer) # function
foo.add_bar_observer(baz.observer) # bound method
foo.add_bar_observer(CallableClass()) # callable instance

foo.notify_bar(3)

答案 1 :(得分:2)

我不能代表共同的方法,但this page(实际副本不可用)有我喜欢的观察者模式的实现。

这是互联网档案链接: http://web.archive.org/web/20060612061259/http://www.suttoncourtenay.org.uk/duncan/accu/pythonpatterns.html

答案 2 :(得分:1)

这完全取决于您的应用程序所需的复杂程度。对于简单事件,回调可能会这样做。对于更复杂的模式和解耦级别,您应该使用某种发布 - 订阅实现,例如PyDispatcher或wxPython的pubsub。

另见this discussion

答案 3 :(得分:1)

我使用过的大多数Python库都为它们的事件通知实现了一个回调模型,我认为这种模型很适合。 Pygtk通过从GObject派生所有对象来实现这一点,Pygtkmvc实现了基于回调的信号处理。 (虽然这是底层C GTK实现的一个特性,但不是受语言启发的。)然而,{{3}}在Pygtk顶部实现观察者模式(和MVC)方面做得很有趣。它使用非常华丽的基于元类的实现,但我发现它在大多数情况下都能很好地工作。如果你有兴趣看到这样做的一种方式,那么代码也很容易理解。

答案 4 :(得分:0)

就个人而言,我只看到过回调。但是,我没有看到那么多事件驱动的python代码所以YMMV。

答案 5 :(得分:0)

我见过使用过听众和回调。但AFAIK没有Python方式。如果相关申请合适,它们应该同样可行。

答案 6 :(得分:0)

matplotlib.cbook模块包含您可能想要查看的类CallbackRegistry。来自documentation

Handle registering and disconnecting for a set of signals and
callbacks:

   signals = 'eat', 'drink', 'be merry'

   def oneat(x):
       print 'eat', x

   def ondrink(x):
       print 'drink', x

   callbacks = CallbackRegistry(signals)

   ideat = callbacks.connect('eat', oneat)
   iddrink = callbacks.connect('drink', ondrink)

   #tmp = callbacks.connect('drunk', ondrink) # this will raise a ValueError

   callbacks.process('drink', 123)    # will call oneat
   callbacks.process('eat', 456)      # will call ondrink
   callbacks.process('be merry', 456) # nothing will be called
   callbacks.disconnect(ideat)        # disconnect oneat
   callbacks.process('eat', 456)      # nothing will be called

您可能不希望依赖matplotlib包。我建议您只需将类复制粘贴到source code中的自己的模块中。

答案 7 :(得分:0)

我正在寻找一种在Python中注册和处理事件的实现。我唯一的体验是使用Gobject,但只使用了PyGtk。它很灵活,但对某些用户来说可能过于复杂。我也遇到过其他一些有趣的候选人,但目前尚不清楚他们是如何相互比较的。