Подтвердить что ты не робот

Python: обратные вызовы, делегаты,...? Что общего?

Просто хочу знать, что такое обычный способ реагировать на события в python. На других языках существует несколько способов, таких как функции обратного вызова, делегаты, структуры-слушатели и т.д. Есть ли общий способ? Какие языковые концепции или дополнительные модули существуют и которые вы можете порекомендовать?

4b9b3361

Ответ 1

Лично я не вижу разницы между обратными вызовами, слушателями и делегатами.

шаблон наблюдателя (так же, как и слушатели, так называемые "множественные обратные вызовы" ) легко реализовать - просто держите список наблюдателей и добавьте или удалите с него вызовы. Эти вызывающие вызовы могут быть функциями, связанными методами или классами с магическим методом __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)

Ответ 3

Все зависит от уровня сложности вашего приложения. Для простых событий, вероятно, будут выполняться обратные вызовы. Для более сложных шаблонов и развязанных уровней вы должны использовать какую-то реализацию публикации-подписки, такую ​​как PyDispatcher или wxPython pubsub.

См. также эту дискуссию.

Ответ 4

Большинство библиотек Python, которые я использовал, используют модель обратного вызова для своих уведомлений о событиях, которые, как мне кажется, подходят для языка довольно хорошо. Pygtk делает это путем вывода всех объектов из GObject, который реализует обработку сигнала на основе обратного вызова. (Хотя это особенность базовой реализации C GTK, а не что-то вдохновленное языком.) Однако Pygtkmvc делает интересную работу реализации шаблона наблюдателя (и MVC) над вершиной Pygtk. Он использует очень богатую реализацию на основе метакласса, но я обнаружил, что он работает достаточно хорошо для большинства случаев. Код также достаточно прост, чтобы следовать, если вы заинтересованы в том, чтобы увидеть один из способов, которым это было сделано.

Ответ 5

Лично я видел только обратные вызовы. Тем не менее, я не видел такого большого количества управляемых событиями кода python, поэтому YMMV.

Ответ 6

Я видел прослушиватели и обратные вызовы. Но AFAIK нет пути Python. Они должны быть одинаково выполнимы, если соответствующая заявка подходит.

Ответ 7

Модуль matplotlib.cbook содержит класс CallbackRegistry, который вы, возможно, захотите посмотреть. Из документация:

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. Я предлагаю вам просто скопировать класс в свой собственный модуль из исходного кода.

Ответ 8

Я ищу реализацию для регистрации и обработки событий в Python. Мой единственный опыт заключается в Gobject, но он использовал его только с PyGtk. Он является гибким, но может быть слишком сложным для некоторых пользователей. Я столкнулся с несколькими другими интересными кандидатами, но не ясно, как именно они сравниваются друг с другом.