darts.util.events

Logiciel capture d'écran:
darts.util.events
Détails logiciels:
Version: 0.4
Date de transfert: 11 May 15
Développeur: Deterministic Arts
Licence: Gratuit
Popularité: 18

Rating: 3.5/5 (Total Votes: 2)

darts.util.events est une bibliothèque Python qui fournit un répartiteur d'événement simple, similaire à la construction de l'événement fournies par le langage C #. & Nbsp; La bibliothèque n'a pas de dépendances externes.
Il a été conçu pour des cas d'utilisation, où les composants émettant des événements et les composants d'écoute pour les événements d'accord sur le type d'événement et la sémantique qui lui sont associés. Cela est vrai, par exemple, pour les gestionnaires d'événement qui écoutent sur "cliquez sur" les événements signalés par les objets de bouton de l'interface graphique, ou notifications signalés par des objets, chaque fois que la valeur de certains changements de propriété. Ceci diffère de l'approche adoptée par, disons, l'PyDispatcher, qui est plus générique, et favorise la communication entre les composants faiblement couplés.
Compatibilité
Le code a été écrit pour et testé avec Python 2.6. Il devrait être compatible à 2.5 aussi bien, mais vous pourriez avoir à insérer un peu de __future__ with_statement lignes d'importation ici et là. Il devrait travailler (ce qui n'a pas été testé) avec d'autres implémentations de Python comme Jython ou IronPython. Notez, cependant, que certains des cas de test définis dans ce fichier pourrait échouer en raison de différentes implémentations de collecte des ordures; ce fichier a été écrit avec CPython à l'esprit.
Documentation
Utilisation de base
& Nbsp; >>> from darts.lib.utils.event importation Editeur, ReferenceRetention RR
& Nbsp; >>> some_event = Editeur ()
L'éditeur est la principale composante. Il sert de greffe pour les rappels / auditeurs. Nous allons définir un auditeur
& Nbsp; >>> imprimante def (*, ** event_args event_keys):
& Nbsp; ... event_args d'impression, event_keys
Pour recevoir des notifications, les clients doivent souscrire à un éditeur. Cela peut être aussi simple que
& Nbsp; >>> some_event.subscribe (imprimante) #doctest: + ELLIPSIS
& Nbsp;
Le résultat de l'appel pour vous inscrire est une instance de (certains sous-classe de) classe d'abonnement. Cette valeur peut être utilisée plus tard, afin d'annuler l'abonnement, quand les notifications ne sont plus souhaitées. La sous-classe réelle est un détail d'implémentation, vous devriez normalement ne se soucient pas. Tout ce que vous devez savoir (et sont autorisés à compter, en fait) est que ce sera une instance de la classe d'abonnement, et il fera tout en a été documenté comme API publique de cette classe (en ce moment: seule méthode annuler) .
Maintenant, nous allons signaler un événement et voir ce qui se passe:
& Nbsp; >>> some_event.publish («un événement»)
& Nbsp; («un événement»,) {}
Comme vous pouvez le voir, l'imprimante a été informé de l'événement, et les imprimés duefully ses arguments à la console.
Annulation abonnements
Comme mentionné, le résultat de l'appel abonnez-vous est un objet de souscription spécial, qui représente l'enregistrement de l'écouteur avec l'éditeur.
& Nbsp; >>> s1 = some_event.subscribe (imprimante)
& Nbsp; >>> some_event.publish («un autre événement ')
& Nbsp; («un autre événement ',) {}
& Nbsp; («un autre événement ',) {}
& Nbsp; >>> s1.cancel ()
& Nbsp; Vrai
& Nbsp; >>> some_event.publish («encore un autre-un»)
& Nbsp; («encore un autre-un»,) {}
L'éditeur est entièrement rentrante. Cela signifie que vous pouvez vous abonner à des événements à partir d'un auditeur, et vous pouvez annuler les abonnements dans ce contexte ainsi:
& Nbsp; >>> def make_canceller (sous-marins):
& Nbsp; ... def auditeur (* unused_1, unused_2 **):
& Nbsp; ... print "Annuler", sous-marins, subs.cancel ()
& Nbsp; ... retour auditeur
& Nbsp; >>> s1 = some_event.subscribe (imprimante)
& Nbsp; >>> s2 = some_event.subscribe (make_canceller (s1))
& Nbsp; >>> some_event.publish («dois-go») #doctest: + ELLIPSIS
& Nbsp; («dois-go ',) {}
& Nbsp; («dois-go ',) {}
& Nbsp; Annuler True
& Nbsp; >>> some_event.publish ('gone') #doctest: + ELLIPSIS
& Nbsp; ('gone',) {}
& Nbsp; Annuler Faux
& Nbsp; >>> s1.cancel ()
& Nbsp; False
Le résultat de l'appel d'annuler nous dit, que la souscription avait déjà été annulée avant l'appel (annulation par notre auditeur magie). Généralement, appelant annuler plusieurs fois est inoffensif; tous, mais le premier appel sont ignorés.
Enlevons maintenant la magie I-peux-annuler-stuff auditeur et se déplacent sur:
& Nbsp; >>> s2.cancel ()
& Nbsp; Vrai
Utilisation non appelables comme rappels
Chaque fois que nous avons fait abonnements ci-dessus, nous avons effectivement simpliee les choses un peu. La signature complète de la méthode est:
& Nbsp; abonnez-def (auditeur [méthode [, reference_retention]])
Examinons d'abord l'argument de la méthode. Jusqu'à présent, nous avons seulement utilisé des objets de fonction à titre d'auditeurs. Fondamentalement, en fait, nous aurions utilisé un objet appelable. Rappelez-vous, que tout objet est "appelable" en Python, si elle fournit une méthode __call__, donc deviner, ce qui est la valeur par défaut de l'argument de la méthode?
& Nbsp; >>> s1 = some_event.subscribe (imprimante, method = "__ call__ ')
& Nbsp; >>> some_event.publish ('foo')
& Nbsp; ('foo',) {}
& Nbsp; ('foo',) {}
& Nbsp; >>> s1.cancel ()
& Nbsp; Vrai
Rien de nouveau. Donc, maintenant, vous pourriez demander: quand dois-je utiliser un autre nom de la méthode?
& Nbsp; >>> cible de classe (objet):
& Nbsp; ... def __init __ (self, nom):
& Nbsp; ... self.name = nom
& Nbsp; ... _callback def (self, * args, ** clés):
& Nbsp; ... print self.name, args, clés
& Nbsp; >>> s1 = some_event.subscribe (cible ('foo'))
& Nbsp; >>> some_event.publish ('! Bumm') #doctest: + ELLIPSIS
& Nbsp; d'enquête (appel le plus récent dernière):
& Nbsp; ...
& Nbsp; TypeError: objet 'cible' est pas appelable
Oups. Enlevons le délinquant, avant que quelqu'un remarque notre erreur:
& Nbsp; >>> s1.cancel ()
& Nbsp; Vrai
& Nbsp; >>> s1 = some_event.subscribe (cible ('foo'), method = '_ rappel')
& Nbsp; >>> some_event.publish ('œuvres!)
& Nbsp; ('!', Œuvres) {}
& Nbsp; foo ('œuvres! »,) {}
Référence rétention
Donc, voilà. Il ya encore un argument inexplorée à en souscrire à gauche, si: reference_retention. Le nom sonne dangereux, mais que fait-il?
& Nbsp; >>> auditeur = cible ('yummy')
& Nbsp; >>> s2 = some_event.subscribe (auditeur, method = '_ rappel', reference_retention = RR.WEAK)
& Nbsp; >>> some_event.publish ('yow')
& Nbsp; ("yow ',) {}
& Nbsp; foo ('yow',) {}
& Nbsp; délicieux («yow ',) {}
Hm. Jusqu'à présent, aucune différence. Faisons un simple changement:
& Nbsp; >>> auditeur = Aucun
& Nbsp; >>> some_event.publish ('yow')
& Nbsp; ("yow ',) {}
& Nbsp; foo ('yow',) {}
Ah. D'Accord. Notre auditeur délicieux est parti. Ce qui s'est passé? Eh bien, en spécifiant une politique de rétention de référence de la faiblesse, nous dit l'éditeur, qu'il doit utiliser une référence faible à l'auditeur vient d'être installé, à la place de la référence forte de défaut. Et après, nous avons publié la seule autre référence forte connue à l'auditeur par la mise en auditeur à Aucun, l'auditeur a été effectivement retiré de l'éditeur. Remarque, BTW., Que l'exemple ci-dessus peut échouer avec python implémentations autres que CPython, en raison de différentes politiques à l'égard de la collecte des ordures. Le principe doit rester valable, si, dans Jython ainsi que IronPython, mais dans ces implémentations, il n'y a aucune garantie, que l'auditeur est retiré dès que la dernière référence est tombé.
Bien sûr, cela fonctionne tout aussi, si la méthode d'être appelé est celui par défaut: __call__:
& Nbsp; >>> def make_listener (nom):
& Nbsp; ... def auditeur (* args, ** clés):
& Nbsp; ... Nom d'impression, args, clés
& Nbsp; ... retour auditeur
& Nbsp; >>> auditeur = make_listener («faible»)
& Nbsp; >>> s2 = some_event.subscribe (auditeur, reference_retention = RR.WEAK)
& Nbsp; >>> some_event.publish («événement»)
& Nbsp; («événement»,) {}
& Nbsp; foo («événement»,) {}
& Nbsp; faible («événement»,) {}
& Nbsp; >>> auditeur = Aucun
& Nbsp; >>> some_event.publish («événement»)
& Nbsp; («événement»,) {}
& Nbsp; foo («événement»,) {}
Voilà tout ce qu'il ya à savoir à propos de la bibliothèque. Comme je l'ai dit plus haut: il est simple, et pourrait ne pas être utile pour tous scenarioes et les cas d'utilisation, mais il fait ce qu'il a été écrit pour.
Gestion des erreurs
La classe Editeur ne vise pas à être sous-. Si vous avez besoin d'adapter le comportement, vous utilisez des objets de stratégie / rappels, qui sont passés au constructeur. À l'heure actuelle, il existe une politique réglable unique, à savoir, le comportement de l'éditeur dans le cas, les auditeurs soulèvent des exceptions:
& Nbsp; >>> def Toobad (événement):
& Nbsp; ... si l'événement == 'augmentation':
& Nbsp; ... générer ValueError
& Nbsp; >>> s1 = some_event.subscribe (Toobad)
& Nbsp; >>> some_event.publish («sans danger»)
& Nbsp; («sans danger»,) {}
& Nbsp; foo («sans danger»,) {}
& Nbsp; >>> some_event.publish («raise»)
& Nbsp; d'enquête (appel le plus récent dernière):
& Nbsp; ...
& Nbsp; ValueError
Comme vous pouvez le voir, le comportement par défaut est de re-relancer l'exception de publier l'intérieur. Cela pourrait ne pas être adéquate selon le cas d'utilisation. En particulier, elle permet d'éviter des écouteurs sont enregistrés plus tard pour être exécuté. Donc, nous allons définir notre propre gestion des erreurs:
& Nbsp; >>> LOG_ERROR def (à l'exception, valeur, retraçage, de souscription, args, touches):
& Nbsp; ... print "attrapé", exception
& Nbsp; >>> éditeur = Editeur (exception_handler = LOG_ERROR)
& Nbsp; >>> publisher.subscribe (Toobad) #doctest: + ELLIPSIS
& Nbsp;
& Nbsp; >>> publisher.subscribe (imprimante) #doctest: + ELLIPSIS
& Nbsp;
& Nbsp; >>> publisher.publish («sans danger»)
& Nbsp; («sans danger»,) {}
& Nbsp; >>> publisher.publish («raise»)
& Nbsp; attrapé
& Nbsp; ('relance',) {}
Comme une alternative à fournir le gestionnaire d'erreur au moment de la construction, vous pouvez également fournir un gestionnaire d'erreurs lors de la publication d'un événement, comme ceci:
& Nbsp; >>> def log_error_2 (à l'exception, valeur, retraçage, de souscription, args, touches):
& Nbsp; ... print "attrapé", exception ", lors de la publication"
& Nbsp; >>> publisher.publish_safely (log_error_2, «raise»)
& Nbsp; attrapé lors de la publication
& Nbsp; ('relance',) {}
Comme vous pouvez le voir, le gestionnaire d'erreurs par appel a la priorité sur le gestionnaire d'erreur par défaut de l'éditeur. Notez qu'il n'y a pas de chaînage, à savoir, si le gestionnaire d'erreur par appel soulève une exception, le gestionnaire par défaut de l'éditeur est pas appelée, mais l'exception est simplement propagé vers l'extérieur à l'appelant de publish_safely: l'éditeur n'a aucun moyen de distinguer entre exceptions soulevées parce que le gestionnaire veut annuler l'envoi et les exceptions soulevées par accident, donc toutes les exceptions soulevées par le gestionnaire sont tout simplement transmises à l'application cliente.
Sécurité des threads
La bibliothèque est thread pleinement conscient et thread-safe. Ainsi, en souscrivant à un auditeur partagé sur plusieurs threads est sûr, et il est donc annulation des abonnements

Ce qui est nouveau dans cette version:.

  • Abonnement gère maintenant fournir un accès à leurs objets d'écouteurs et les noms de méthodes. Ceci a été ajouté pour le bien de code d'erreur de manipulation, qui veut se connecter exceptions et de fournir une meilleure façon d'identifier l'auditeur réelle, qui est allé voyous.

Quoi de neuf dans la version 0.2:

  • La gestion des erreurs a été changé. Au lieu d'une sous-classe de l'éditeur, le gestionnaire d'exception par défaut est maintenant passé comme rappel à l'éditeur lors de la construction. La classe Editeur est maintenant documenté comme & quot; pas destinée à être sous-classé & quot;.

Exigences :

  • Python

Commentaires à darts.util.events

Commentaires non trouvées
Ajouter un commentaire
Tourner sur les images!