Forfaits PyPI
En date de juin 2020, ce sont les packages liés à l'événement disponibles sur PyPI, classés par date de sortie la plus récente.
Il y a plus
C'est beaucoup de bibliothèques à choisir, en utilisant une terminologie très différente (événements, signaux, gestionnaires, répartition des méthodes, hooks, ...).
J'essaie de garder un aperçu des packages ci-dessus, ainsi que des techniques mentionnées dans les réponses ici.
Tout d'abord, une terminologie ...
Modèle d'observateur
Le style le plus élémentaire du système d'événements est le «sac de méthodes de gestion», qui est une implémentation simple du modèle Observer .
Fondamentalement, les méthodes de gestionnaire (callables) sont stockées dans un tableau et sont chacune appelées lorsque l'événement se déclenche.
Publier-s'abonner
L'inconvénient des systèmes d'événements Observer est que vous ne pouvez enregistrer les gestionnaires que sur l'objet Event réel (ou la liste des gestionnaires). Donc, au moment de l'inscription, l'événement doit déjà exister.
C'est pourquoi le deuxième style de systèmes d'événements existe: le
modèle de publication-abonnement . Ici, les gestionnaires ne s'inscrivent pas sur un objet événement (ou une liste de gestionnaires), mais sur un répartiteur central. De plus, les notifiants ne parlent qu'au répartiteur. Ce à écouter ou à publier est déterminé par le «signal», qui n'est rien de plus qu'un nom (chaîne).
Motif médiateur
Peut-être aussi intéressant: le modèle Mediator .
Crochets
Un système «hook» est généralement utilisé dans le contexte des plugins d'application. L'application contient des points d'intégration fixes (hooks), et chaque plug-in peut se connecter à ce hook et effectuer certaines actions.
Autres événements'
Remarque: threading.Event n'est pas un «système d'événements» dans le sens ci-dessus. C'est un système de synchronisation de threads où un thread attend qu'un autre thread «signale» l'objet Event.
Les bibliothèques de messagerie réseau utilisent souvent aussi le terme «événements»; parfois ceux-ci sont similaires dans leur concept; parfois non. Ils peuvent bien sûr franchir les limites des threads, des processus et des ordinateurs. Voir par exemple
pyzmq , pymq ,
Twisted , Tornado , gevent , eventlet .
Références faibles
En Python, détenir une référence à une méthode ou un objet garantit qu'il ne sera pas supprimé par le garbage collector. Cela peut être souhaitable, mais cela peut également entraîner des fuites de mémoire: les gestionnaires liés ne sont jamais nettoyés.
Certains systèmes d'événements utilisent des références faibles au lieu de références régulières pour résoudre ce problème.
Quelques mots sur les différentes bibliothèques
Systèmes d'événements de type observateur:
- zope.event montre les os nus de comment cela fonctionne (voir la réponse de Lennart ). Remarque: cet exemple ne prend même pas en charge les arguments du gestionnaire.
- « Liste » appelable de LongPoke mise en œuvre de montre qu'un tel système d'événements peut être mis en œuvre très minimalistically par le sous - classement
list
.
- La variation EventHook de Felk garantit également les signatures des appelants et des appelants.
- Le EventHook de spassig (le modèle d'événement de Michael Foord) est une implémentation simple.
- La classe d'événement Valued Lessons de Josip est fondamentalement la même, mais utilise un
set
au lieu d'un list
pour stocker le sac, et met en œuvre __call__
des ajouts raisonnables.
- PyNotify est similaire dans son concept et fournit également des concepts supplémentaires de variables et de conditions («événement changé de variable»). La page d'accueil n'est pas fonctionnelle.
- axel est essentiellement un sac de-gestionnaires avec plus de fonctionnalités liées à filetage, la gestion des erreurs, ...
- python-dispatch nécessite la dérivation des classes sources paires
pydispatch.Dispatcher
.
- buslane est basé sur une classe, prend en charge un ou plusieurs gestionnaires et facilite des conseils de type étendus.
- L' observateur / événement de Pithikos est un modèle léger.
Bibliothèques de publication-abonnement:
- blinker a quelques fonctionnalités astucieuses telles que la déconnexion automatique et le filtrage basé sur l'expéditeur.
- PyPubSub est un package stable, et promet "des fonctionnalités avancées qui facilitent le débogage et la maintenance des rubriques et des messages".
- pymitter est un port Python de Node.js EventEmitter2 et propose des espaces de noms, des caractères génériques et TTL.
- PyDispatcher semble mettre l'accent sur la flexibilité en ce qui concerne la publication plusieurs-à-plusieurs, etc. Prend en charge les références faibles.
- louie est un PyDispatcher retravaillé et devrait fonctionner "dans une grande variété de contextes".
- pypydispatcher est basé sur (vous l'avez deviné ...) PyDispatcher et fonctionne également dans PyPy.
- django.dispatch est un PyDispatcher réécrit "avec une interface plus limitée, mais des performances supérieures".
- pyeventdispatcher est basé sur le répartiteur d'événements du framework Symfony de PHP.
- dispatcher a été extrait de django.dispatch mais devient assez ancien.
- EventManger de Cristian Garcia est une implémentation très courte.
Autres:
- pluggy contient un système de hook utilisé par les
pytest
plugins.
- RxPy3 implémente le modèle observable et permet de fusionner des événements, de réessayer, etc.
- Les signaux et emplacements de Qt sont disponibles sur PyQt
ou PySide2 . Ils fonctionnent comme rappel lorsqu'ils sont utilisés dans le même thread, ou comme événements (à l'aide d'une boucle d'événements) entre deux threads différents. Les signaux et les emplacements ont la limitation de ne fonctionner que dans les objets des classes qui en dérivent
QObject
.
Je l'ai fait de cette façon:
Cependant, comme avec tout ce que j'ai vu, il n'y a pas de pydoc généré automatiquement pour cela, et pas de signatures, ce qui est vraiment nul.
la source
_bag_of_handlers
qui est une liste. La méthode add de la classe serait simplementself._bag_of_handlers.append(some_callable)
. La méthode fire de la classe ferait une boucle à travers `_bag_of_handlers` en passant les arguments et kwargs fournis aux gestionnaires et les exécuterait l'un après l'autre.Nous utilisons un EventHook comme suggéré par Michael Foord dans son modèle d'événement :
Ajoutez simplement des EventHooks à vos cours avec:
Nous ajoutons la fonctionnalité pour supprimer tous les écouteurs d'un objet dans la classe Michaels et nous nous sommes retrouvés avec ceci:
la source
self.__handlers = [h for h in self._handlers if getattr(h, 'im_self', False) != obj]
J'utilise zope.event . Ce sont les os les plus nus que vous puissiez imaginer. :-) En fait, voici le code source complet:
Notez que vous ne pouvez pas envoyer de messages entre les processus, par exemple. Ce n'est pas un système de messagerie, juste un système d'événements, rien de plus, rien de moins.
la source
J'ai trouvé ce petit script sur Valued Lessons . Il semble avoir juste le bon rapport simplicité / puissance que je recherche. Peter Thatcher est l'auteur du code suivant (aucune licence n'est mentionnée).
la source
Voici un design minimal qui devrait bien fonctionner. Ce que vous devez faire, c'est simplement hériter
Observer
d'une classe et ensuite l'utiliserobserve(event_name, callback_fn)
pour écouter un événement spécifique. Chaque fois que cet événement spécifique est déclenché n'importe où dans le code (c'est-à-dire.Event('USB connected')
), Le rappel correspondant se déclenche.Exemple:
la source
J'ai créé une
EventManager
classe (code à la fin). La syntaxe est la suivante:Voici un exemple:
Production:
Code EventManger:
la source
Vous pouvez jeter un œil au pymitter ( pypi ). C'est une petite approche à fichier unique (~ 250 loc) "fournissant des espaces de noms, des caractères génériques et TTL".
Voici un exemple de base:
la source
J'ai fait une variation de l'approche minimaliste de Longpoke qui garantit également les signatures des appelants et des appelants:
la source
Si je fais du code dans pyQt j'utilise le paradigme des sockets / signaux QT, c'est la même chose pour Django
Si je fais des E / S asynchrones, j'utilise le module de sélection natif
Si j'utilise un analyseur python SAX, j'utilise l'API d'événements fournie par SAX. Il semble donc que je suis victime de l'API sous-jacente :-)
Vous devriez peut-être vous demander ce que vous attendez du cadre / module d'événement. Ma préférence personnelle est d'utiliser le paradigme Socket / Signal de QT. plus d'informations à ce sujet peuvent être trouvées ici
la source
Voici un autre module à considérer. Cela semble un choix viable pour les applications plus exigeantes.
la source
Si vous vouliez faire des choses plus compliquées comme fusionner des événements ou réessayer, vous pouvez utiliser le modèle Observable et une bibliothèque mature qui implémente cela. https://github.com/ReactiveX/RxPY . Les observables sont très courants en Javascript et Java et très pratiques à utiliser pour certaines tâches asynchrones.
SORTIE :
la source
Si vous avez besoin d'un bus d'événements qui fonctionne au-delà des frontières du processus ou du réseau, vous pouvez essayer PyMQ . Il prend actuellement en charge pub / sub, les files d'attente de messages et le RPC synchrone. La version par défaut fonctionne au-dessus d'un backend Redis, vous avez donc besoin d'un serveur Redis en cours d'exécution. Il existe également un backend en mémoire pour les tests. Vous pouvez également écrire votre propre backend.
Pour initialiser le système:
Avertissement: je suis l'auteur de cette bibliothèque
la source
Vous pouvez essayer le
buslane
module.Cette bibliothèque facilite la mise en œuvre d'un système basé sur les messages. Il prend en charge les commandes (gestionnaire unique) et les événements (0 ou gestionnaires multiples). Buslane utilise des annotations de type Python pour enregistrer correctement le gestionnaire.
Exemple simple:
Pour installer buslane, utilisez simplement pip:
la source
Il y a quelque temps, j'ai écrit une bibliothèque qui pourrait vous être utile. Il vous permet d'avoir des écouteurs locaux et globaux, plusieurs façons différentes de les enregistrer, la priorité d'exécution, etc.
Jetez un œil pyeventdispatcher
la source