Pakiety PyPI
Od czerwca 2020 r. Są to pakiety związane ze zdarzeniami dostępne w PyPI, uporządkowane według ostatniej daty wydania.
Jest więcej
Jest wiele bibliotek do wyboru, przy użyciu bardzo różnych terminów (zdarzenia, sygnały, procedury obsługi, wysyłanie metod, przechwytywanie, ...).
Staram się zachować przegląd powyższych pakietów oraz techniki wymienione w odpowiedziach tutaj.
Po pierwsze, trochę terminologii ...
Wzór obserwatora
Najbardziej podstawowym stylem systemu zdarzeń jest „torba metod obsługi”, która jest prostą implementacją wzorca Observer .
Zasadniczo metody modułu obsługi (wywołania) są przechowywane w tablicy i każda z nich jest wywoływana, gdy zdarzenie „odpala”.
Publikuj-Subskrybuj
Wadą systemów zdarzeń Observer jest to, że można zarejestrować procedury obsługi tylko w rzeczywistym obiekcie Event (lub liście procedur obsługi). W momencie rejestracji wydarzenie musi już istnieć.
Dlatego istnieje drugi styl systemów zdarzeń:
wzorzec publikowania-subskrybowania . W tym przypadku procedury obsługi nie rejestrują się w obiekcie zdarzenia (lub liście procedur obsługi), ale w centralnym programie dyspozytorskim. Powiadamiający rozmawiają tylko z dyspozytorem. O czym nasłuchiwać, a co publikować, decyduje „sygnał”, który jest niczym innym jak nazwą (ciągiem).
Wzór mediatora
Może również być interesujące: wzór Mediatora .
Haki
System „hook” jest zwykle używany w kontekście wtyczek aplikacji. Aplikacja zawiera stałe punkty integracji (zaczepy), a każda wtyczka może połączyć się z tym zaczepem i wykonać określone czynności.
Inne wydarzenia'
Uwaga: Threading.Event nie jest „systemem zdarzeń” w powyższym znaczeniu. Jest to system synchronizacji wątków, w którym jeden wątek czeka, aż inny wątek „zasygnalizuje” obiekt Event.
Biblioteki wiadomości sieciowych często używają również terminu „zdarzenia”; czasami są one podobne pod względem koncepcji; czasami nie. Mogą oczywiście przekraczać granice nici, procesu i komputera. Patrz np.
Pyzmq , pymq ,
Twisted , Tornado , gevent , eventlet .
Słabe referencje
W Pythonie trzymanie odwołania do metody lub obiektu zapewnia, że nie zostanie ono usunięte przez moduł odśmiecający. Może to być pożądane, ale może również prowadzić do wycieków pamięci: powiązane programy obsługi nigdy nie są usuwane.
Niektóre systemy zdarzeń używają słabych referencji zamiast zwykłych, aby rozwiązać ten problem.
Kilka słów o różnych bibliotekach
Systemy wydarzeń w stylu obserwatora:
- zope.event pokazuje gołe kości tego, jak to działa (patrz odpowiedź Lennarta ). Uwaga: ten przykład nie obsługuje nawet argumentów modułu obsługi.
- Implementacja „listy wywołań” LongPoke pokazuje, że taki system zdarzeń można wdrożyć bardzo minimalistycznie przez podklasowanie
list
.
- Odmiana Felk EventHook zapewnia również podpisy osób biorących udział i dzwoniących.
- EventHook Spassiga (wzorzec zdarzenia Michaela Foorda ) to prosta implementacja.
- Klasa Eventu Cennych Lekcji Josipa jest zasadniczo taka sama, ale używa
set
zamiast zamiast a list
do przechowywania torby i narzędzi, __call__
które są rozsądnymi dodatkami.
- PyNotify ma podobną koncepcję, a także zapewnia dodatkowe koncepcje zmiennych i warunków („zmienne zdarzenie zmienione”). Strona główna nie działa.
- axel to w zasadzie torba z uchwytami z wieloma funkcjami związanymi z gwintowaniem, obsługą błędów, ...
- Python-dispatch wymaga wyprowadzenia parzystych klas źródłowych
pydispatch.Dispatcher
.
- buslane jest oparty na klasach, obsługuje pojedyncze lub wielokrotne moduły obsługi i ułatwia obszerne wskazówki dotyczące typów.
- Pithikos ' Observer / Event to lekka konstrukcja.
Publikuj i subskrybuj biblioteki:
- migacz ma kilka fajnych funkcji, takich jak automatyczne rozłączanie i filtrowanie w oparciu o nadawcę.
- PyPubSub jest stabilnym pakietem i obiecuje „zaawansowane funkcje ułatwiające debugowanie i zarządzanie tematami i wiadomościami”.
- pymitter jest portem Python w Node.js EventEmitter2 i oferuje przestrzenie nazw, symbole wieloznaczne i TTL.
- PyDispatcher wydaje się kłaść nacisk na elastyczność w odniesieniu do publikacji „wiele do wielu” itp. Obsługuje słabe referencje.
- Louie jest przerobionym PyDispatcherem i powinien działać „w szerokim zakresie kontekstów”.
- pypydispatcher jest oparty na (zgadłeś ...) PyDispatcher, a także działa w PyPy.
- django.dispatch to przerobiony PyDispatcher „z bardziej ograniczonym interfejsem, ale o wyższej wydajności”.
- pyeventdispatcher opiera się na narzędziu do wysyłania zdarzeń frameworku Symfony w PHP
- dispatcher został wyodrębniony z django.dispatch, ale robi się już dość stary.
- EventManger Cristiana Garcii to naprawdę krótkie wdrożenie.
Inne:
- pluggy zawiera system haka używany przez
pytest
wtyczki.
- RxPy3 implementuje wzorzec obserwowalny i umożliwia scalanie zdarzeń, ponawianie itp.
- Sygnały i gniazda Qt są dostępne w PyQt
lub PySide2 . Działają one jako wywołanie zwrotne, gdy są używane w tym samym wątku lub jako zdarzenia (przy użyciu pętli zdarzeń) między dwoma różnymi wątkami. Sygnały i gniazda mają takie ograniczenie, że działają tylko w obiektach klas, które się z nich wywodzą
QObject
.
Robiłem to w ten sposób:
Jednak, podobnie jak w przypadku wszystkiego, co widziałem, nie ma do tego automatycznie generowanego pydoc i żadnych podpisów, co naprawdę jest do kitu.
źródło
_bag_of_handlers
która jest listą. Metoda dodawania klasy byłaby po prostuself._bag_of_handlers.append(some_callable)
. Metoda ogniowa klasy przechodziłaby przez „_bag_of_handler”, przekazując dostarczone argumenty i kwargs do procedur obsługi i wykonując je kolejno.Używamy EventHook zgodnie z sugestią Michaela Foorda w jego Wzorze wydarzenia :
Po prostu dodaj EventHook do swoich zajęć za pomocą:
Dodajemy funkcję usuwania wszystkich detektorów z obiektu do klasy Michaels i otrzymaliśmy:
źródło
self.__handlers = [h for h in self._handlers if getattr(h, 'im_self', False) != obj]
Używam zope.event . To najbardziej nagie kości, jakie możesz sobie wyobrazić. :-) Oto pełny kod źródłowy:
Pamiętaj, że nie możesz na przykład wysyłać wiadomości między procesami. To nie jest system wiadomości, tylko system zdarzeń, nic więcej, nic więcej.
źródło
Znalazłem ten mały skrypt w Valued Lessons . Wygląda na to, że mam odpowiedni stosunek prostoty do mocy, o który mi chodzi. Peter Thatcher jest autorem następującego kodu (nie wspomniano o licencjonowaniu).
źródło
Oto minimalny projekt, który powinien działać dobrze. Musisz po prostu odziedziczyć
Observer
w klasie, a następnie użyćobserve(event_name, callback_fn)
nasłuchiwać określonego zdarzenia. Za każdym razem, gdy to konkretne zdarzenie zostanie uruchomione w dowolnym miejscu kodu (tj.Event('USB connected')
), Odpowiednie wywołanie zwrotne będzie uruchamiane.Przykład:
źródło
Stworzyłem
EventManager
klasę (kod na końcu). Składnia jest następująca:Oto przykład:
Wynik:
Kod EventManger:
źródło
Być może trzeba spojrzeć na pymitter ( PyPI ). Jest to małe podejście z pojedynczym plikiem (~ 250 loc) „zapewniające przestrzenie nazw, symbole wieloznaczne i TTL”.
Oto podstawowy przykład:
źródło
Zrobiłem odmianę minimalistycznego podejścia Longpoke, które zapewnia również podpisy zarówno dla osób odbierających, jak i dzwoniących:
źródło
Jeśli piszę kod w pyQt, używam paradygmatu gniazd / sygnałów QT, to samo dotyczy django
Jeśli wykonuję asynchroniczne operacje we / wy, użyj natywnego modułu wyboru
Jeśli używam parsera python SAX, korzystam z interfejsu API zdarzeń dostarczonego przez SAX. Wygląda na to, że jestem ofiarą bazowego API :-)
Może powinieneś zadać sobie pytanie, czego oczekujesz od frameworku / modułu eventu. Osobiście wolę używać paradygmatu Socket / Signal firmy QT. więcej informacji na ten temat można znaleźć tutaj
źródło
Oto kolejny moduł do rozważenia. Wydaje się realnym wyborem dla bardziej wymagających aplikacji.
źródło
Jeśli chcesz robić bardziej skomplikowane rzeczy, takie jak scalanie zdarzeń lub ponawiać próbę, możesz użyć Wzorca Observable i dojrzałej biblioteki, która to implementuje. https://github.com/ReactiveX/RxPY . Obserwowalne są bardzo powszechne w Javascript i Java i bardzo wygodne w użyciu do niektórych zadań asynchronicznych.
WYDAJNOŚĆ :
źródło
Jeśli potrzebujesz magistrali zdarzeń, która działa poza granicami procesu lub sieci, możesz wypróbować PyMQ . Obecnie obsługuje pub / sub, kolejki komunikatów i synchroniczne RPC. Domyślna wersja działa na bazie backendu Redis, więc potrzebujesz działającego serwera Redis. Istnieje również backend w pamięci do testowania. Możesz także napisać własny backend.
Aby zainicjować system:
Oświadczenie: Jestem autorem tej biblioteki
źródło
Możesz spróbować
buslane
moduł.Ta biblioteka ułatwia implementację systemu opartego na komunikatach. Obsługuje podejście poleceń (pojedynczy moduł obsługi) i zdarzeń (0 lub wiele modułów obsługi). Buslane używa adnotacji typu Python, aby poprawnie zarejestrować moduł obsługi.
Prosty przykład:
Aby zainstalować buslane, po prostu użyj pip:
źródło
Jakiś czas temu napisałem bibliotekę, która może ci się przydać. Pozwala mieć lokalnych i globalnych słuchaczy, wiele różnych sposobów ich rejestrowania, priorytet wykonania i tak dalej.
Spójrz pyeventdispatcher
źródło