Просто хочу знать, что такое обычный способ реагировать на события в python. На других языках существует несколько способов, таких как функции обратного вызова, делегаты, структуры-слушатели и т.д. Есть ли общий способ? Какие языковые концепции или дополнительные модули существуют и которые вы можете порекомендовать?
Python: обратные вызовы, делегаты,...? Что общего?
Ответ 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)
Ответ 2
Я не могу говорить об общих подходах, но эта страница (фактическая копия недоступна) имеет реализация шаблона наблюдателя, который мне нравится.
Здесь ссылка Internet Archive: http://web.archive.org/web/20060612061259/http://www.suttoncourtenay.org.uk/duncan/accu/pythonpatterns.html
Ответ 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. Он является гибким, но может быть слишком сложным для некоторых пользователей. Я столкнулся с несколькими другими интересными кандидатами, но не ясно, как именно они сравниваются друг с другом.
- Pyevent, обертка libevent.
- Событие Zope