Пакеты PyPI
По состоянию на июнь 2020 года эти пакеты, связанные с событиями, доступны в PyPI и упорядочены по дате последнего выпуска.
Есть еще кое-что
Из множества библиотек можно выбирать, используя совершенно разную терминологию (события, сигналы, обработчики, диспетчеризация методов, перехватчики, ...).
Я пытаюсь держать обзор вышеупомянутых пакетов, плюс методы, упомянутые в ответах здесь.
Сначала немного терминологии ...
Образец наблюдателя
Самым основным стилем системы событий является «пакет методов обработки», который представляет собой простую реализацию шаблона Observer .
По сути, методы-обработчики (callables) хранятся в массиве и каждый из них вызывается, когда событие «срабатывает».
Опубликовать-Подписка
Недостаток систем событий Observer заключается в том, что вы можете зарегистрировать обработчики только для реального объекта Event (или списка обработчиков). Таким образом, на момент регистрации событие уже должно существовать.
Вот почему существует второй стиль систем событий:
шаблон публикации-подписки . Здесь обработчики регистрируются не в объекте события (или списке обработчиков), а в центральном диспетчере. Также уведомители общаются только с диспетчером. Что слушать или что публиковать, определяется «сигналом», который является не чем иным, как именем (строкой).
Образец медиатора
Может также представлять интерес: модель Посредника .
Крючки
Система «крючка» обычно используется в контексте плагинов приложения. Приложение содержит фиксированные точки интеграции (хуки), и каждый плагин может подключаться к этому хуку и выполнять определенные действия.
Другие «события»
Примечание: threading.Event не является «системой событий» в вышеприведенном смысле. Это система синхронизации потоков, в которой один поток ожидает, пока другой поток не «сигнализирует» объект Event.
Библиотеки сетевых сообщений также часто используют термин «события»; иногда они похожи по концепции; иногда нет. Конечно, они могут пересекать границы потоков, процессов и компьютеров. См. Например,
pyzmq , pymq ,
Twisted , Tornado , gevent , eventlet .
Слабые ссылки
В Python хранение ссылки на метод или объект гарантирует, что он не будет удален сборщиком мусора. Это может быть желательно, но также может привести к утечкам памяти: связанные обработчики никогда не очищаются.
Некоторые системы событий используют слабые ссылки вместо обычных для решения этой проблемы.
Несколько слов о различных библиотеках
Системы событий в стиле наблюдателя:
- zope.event показывает, как это работает (см . ответ Леннарта ). Примечание: этот пример даже не поддерживает аргументы обработчика.
- Реализация LongPoke 'callable list' показывает, что такая система событий может быть реализована очень минималистично с помощью подклассов
list
.
- Вариант Felk EventHook также обеспечивает подписи вызывающих и вызывающих абонентов.
- EventHook от spassig (шаблон событий Майкла Фурда ) является простой реализацией.
- Класс Josip's Valued Lessons Event в основном тот же, но использует
set
вместо a list
для хранения сумки и реализует, __call__
которые являются разумными дополнениями.
- PyNotify похожа по своей концепции, а также предоставляет дополнительные понятия о переменных и условиях («событие изменения переменной»). Домашняя страница не работает.
- Axel - это, по сути, мешок с обработчиками, с большим количеством функций, связанных с многопоточностью, обработкой ошибок, ...
- Для python-dispatch требуются классы с четным исходным кодом
pydispatch.Dispatcher
.
- buslane основан на классах, поддерживает одно- или многократные обработчики и облегчает обширные подсказки типов.
- Pithikos ' Observer / Event - это легкий дизайн.
Библиотеки публикации-подписки:
- Blinker имеет несколько отличных функций, таких как автоматическое отключение и фильтрация по отправителю.
- PyPubSub является стабильным пакетом и обещает «расширенные функции, которые облегчают отладку и поддержку тем и сообщений».
- pymitter является портом Python Node.js EventEmitter2 и предлагает пространства имен, подстановочные знаки и TTL.
- PyDispatcher, кажется, подчеркивает гибкость в отношении публикации «многие ко многим» и т. Д. Поддерживает слабые ссылки.
- Луи является переработанным PyDispatcher и должен работать «в самых разных контекстах».
- pypydispatcher основан на (как вы уже догадались ...) PyDispatcher, а также работает в PyPy.
- django.dispatch - это переписанный PyDispatcher «с более ограниченным интерфейсом, но более высокой производительностью».
- pyeventdispatcher основан на диспетчере событий PHP-платформы Symfony.
- диспетчер был извлечен из django.dispatch, но становится довольно старым.
- EventManger Кристиана Гарсии - очень короткая реализация.
Другие:
- pluggy содержит систему хуков, которая используется
pytest
плагинами.
- RxPy3 реализует шаблон Observable и позволяет объединять события, повторять попытки и т. Д.
- Сигналы и слоты Qt доступны в PyQt
или PySide2 . Они работают как обратный вызов, когда используются в одном потоке, или как события (используя цикл событий) между двумя разными потоками. Сигналы и слоты имеют ограничение, что они работают только в объектах классов, которые являются производными
QObject
.
Я делал это так:
Однако, как и со всем остальным, что я видел, для этого не существует автоматически сгенерированного pydoc и подписей, которые действительно отстой.
источник
_bag_of_handlers
которая является списком. Метод добавления класса будет простоself._bag_of_handlers.append(some_callable)
. Метод огня класса будет проходить через _bag_of_handlers`, передавая предоставленные аргументы и kwargs обработчикам и выполняя каждый из них по очереди.Мы используем EventHook, как это было предложено Майклом Фурдом в его паттерне событий. :
Просто добавьте EventHooks в ваши классы с помощью:
Мы добавили функциональность для удаления всех слушателей из объекта в класс Michaels и получили следующее:
источник
self.__handlers = [h for h in self._handlers if getattr(h, 'im_self', False) != obj]
Я использую zope.event . Это самые голые кости, которые вы можете себе представить. :-) На самом деле, вот полный исходный код:
Обратите внимание, что вы не можете отправлять сообщения между процессами, например. Это не система обмена сообщениями, просто система событий, ни больше, ни меньше.
источник
Я нашел этот небольшой сценарий на Ценных уроках . Кажется, у меня просто правильное соотношение простоты и мощности. Питер Тэтчер является автором следующего кода (лицензирование не упоминается).
источник
Вот минимальный дизайн, который должен работать нормально. Что вам нужно сделать, это просто наследовать
Observer
в классе, а затем использоватьobserve(event_name, callback_fn)
для прослушивания определенного события. Всякий раз, когда это конкретное событие вызывается где-либо в коде (т. Е.Event('USB connected')
), Срабатывает соответствующий обратный вызов.Пример:
источник
Я создал
EventManager
класс (код в конце). Синтаксис следующий:Вот пример:
Вывод:
Код EventManger:
источник
Вы можете взглянуть на pymitter ( pypi ). Это небольшой однофайловый подход (~ 250 loc), "обеспечивающий пространства имен, подстановочные знаки и TTL".
Вот основной пример:
источник
Я сделал вариант минималистичного подхода Longpoke, который также обеспечивает подписи как для вызывающих, так и для вызывающих абонентов:
источник
Если я делаю код в pyQt, я использую парадигму сокетов / сигналов QT, то же самое для django
Если я делаю асинхронный ввод-вывод, используйте родной модуль выбора
Если я использую синтаксический анализатор SAX Python, я использую API событий, предоставляемый SAX. Так что, похоже, я жертва базового API :-)
Может быть, вы должны спросить себя, что вы ожидаете от рамки событий / модуля. Лично я предпочитаю использовать парадигму Socket / Signal от QT. больше информации об этом можно найти здесь
источник
Вот еще один модуль для рассмотрения. Это кажется приемлемым выбором для более требовательных приложений.
источник
Если вы хотите сделать более сложные вещи, такие как объединение событий или повторение, вы можете использовать шаблон Observable и зрелую библиотеку, которая реализует это. https://github.com/ReactiveX/RxPY . Observables очень распространены в Javascript и Java, и их очень удобно использовать для некоторых асинхронных задач.
ВЫХОД :
источник
Если вам нужна шина событий, которая работает через границы процессов или сетей, вы можете попробовать PyMQ . В настоящее время он поддерживает pub / sub, очереди сообщений и синхронный RPC. Версия по умолчанию работает поверх бэкэнда Redis, поэтому вам нужен работающий сервер Redis. Существует также внутренняя память для тестирования. Вы также можете написать свой собственный бэкэнд.
Для инициализации системы:
Отказ от ответственности: я являюсь автором этой библиотеки
источник
Вы можете попробовать
buslane
модуль.Эта библиотека облегчает реализацию системы, основанной на сообщениях. Он поддерживает команды (один обработчик) и события (0 или несколько обработчиков). Buslane использует аннотации типа Python для правильной регистрации обработчика.
Простой пример:
Чтобы установить buslane, просто используйте pip:
источник
Некоторое время назад я написал библиотеку, которая может быть полезна для вас. Это позволяет вам иметь локальных и глобальных слушателей, несколько разных способов их регистрации, приоритет выполнения и так далее.
Посмотрите pyeventdispatcher
источник