darts.util.events

Screenshot der Software:
darts.util.events
Softwarebeschreibung:
Version: 0.4
Upload-Datum: 11 May 15
Entwickler: Deterministic Arts
Lizenz: Frei
Popularität: 18

Rating: 3.5/5 (Total Votes: 2)

darts.util.events ist eine Python-Bibliothek, die eine einfache Event-Dispatcher, ähnlich zu dem Fall Konstrukt durch die Sprache C # zur Verfügung gestellt bietet. & Nbsp; Die Bibliothek hat keine externen Abhängigkeiten.
Es wurde für Anwendungsfälle, bei denen die Komponenten emittierenden Ereignissen und die Komponenten Hören für Veranstaltungen einig über die Art der Veranstaltung und der Semantik zugeordnet vorgesehen. Dies gilt beispielsweise für die Event-Handler, die auf hören "klicken Sie auf" Ereignisse von GUI Schaltfläche Objekte, oder Benachrichtigungen per Objekte signalisiert signalisiert, wenn der Wert einiger Eigenschaft ändert. Dies unterscheidet sich von dem Ansatz, sagen getroffen, die PyDispatcher, die generische ist, und begünstigt die Kommunikation zwischen den schwach gekoppelten Komponenten.
Kompatibilität
Der Code wurde geschrieben und mit Python 2.6 getestet. Es sollte aber auch kompatibel zu 2.5, aber Sie haben könnten, um nur einige von __future__ import with_statement Zeilen hier und dort einfügen. Es sollte funktionieren (dies wurde nicht geprüft) mit alternativen Implementierungen von Python wie Jython oder Ironpython. Beachten Sie jedoch, dass einige der Testfälle in dieser Datei definierten könnte auf verschiedene Garbage Collection-Implementierungen scheitern; Diese Datei wurde mit CPython im Hinterkopf geschrieben.
Dokumentation
Grundfunktionen
& Nbsp; von darts.lib.utils.event >>> import Publisher, ReferenceRetention als RR
& Nbsp; >>> some_event = Publisher ()
Der Publisher ist die Hauptkomponente. Es fungiert als Registrierungsstelle für Rückrufe / Zuhörer. Wir definieren einen Listener
& Nbsp; >>> def Drucker (* event_args, ** event_keys):
& Nbsp; ... print event_args, event_keys
Um Benachrichtigungen zu erhalten, müssen die Clients an einen Verlag zu abonnieren. Dies kann so einfach sein wie
& Nbsp; >>> some_event.subscribe (Drucker) #doctest: + ELLIPSIS
& Nbsp;
Das Ergebnis des Aufrufs zur Zeichnung ist eine Instanz (einige Unterklasse) Klasse Subscription. Dieser Wert kann später verwendet werden, um das Abonnement kündigen, wenn Meldungen nicht mehr erwünscht. Die tatsächliche Unterklasse ist eine Implementierung Detail, sollten in der Regel nicht kümmern. Alles, was Sie wissen müssen (und dürfen sich verlassen, in der Tat) ist, dass es eine Instanz der Klasse Abonnement zu sein, und es wird liefern, was als öffentliche API der Klasse dokumentiert wurde (jetzt: einzige Methode abbrechen) .
Jetzt wollen wir signalisieren ein Ereignis und sehen, was passiert:
& Nbsp; >>> some_event.publish ('an-Ereignis ")
& Nbsp; ('an-Ereignis',) {}
Wie Sie sehen können, hat der Drucker der Veranstaltung mitgeteilt wurde, und duefully gedruckt die ihre Argumente an die Konsole.
Cancelling Abonnements
Wie bereits erwähnt, ist das Ergebnis der Aufruf unterzeichnen eine besondere Bezugsobjekt, das die Registrierung des Hörers mit dem Verlag stellt.
& Nbsp; >>> s1 = some_event.subscribe (Drucker)
& Nbsp; >>> some_event.publish ("another-Ereignis")
& Nbsp; ('another-Ereignis',) {}
& Nbsp; ('another-Ereignis',) {}
& Nbsp; >>> s1.cancel ()
& Nbsp; Wahr
& Nbsp; >>> some_event.publish ('noch-another-one')
& Nbsp; ('noch-another-one',) {}
Der Verlag ist voll reentrant. Das bedeutet, dass Sie, um Ereignisse aus einem Zuhörer zu abonnieren, und Sie können Abonnements in diesem Zusammenhang auch zu stornieren:
& Nbsp; >>> def make_canceller (subs):
& Nbsp; ... def Hörer (* unused_1, ** unused_2):
& Nbsp; ... print "Abbrechen", U-Boote, subs.cancel ()
& Nbsp; ... Rückkehr Zuhörer
& Nbsp; >>> s1 = some_event.subscribe (Drucker)
& Nbsp; >>> s2 = some_event.subscribe (make_canceller (s1))
& Nbsp; >>> some_event.publish ("Gotta go ') #doctest: + ELLIPSIS
& Nbsp; ("Gotta go ',) {}
& Nbsp; ("Gotta go ',) {}
& Nbsp; Abbrechen True
& Nbsp; >>> some_event.publish ("gone") #doctest: + ELLIPSIS
& Nbsp; ("gone") {}
& Nbsp; Abbrechen False
& Nbsp; >>> s1.cancel ()
& Nbsp; Falsch
Das Ergebnis des Aufrufs zum Abbrechen sagt uns, dass das Abonnement bereits vor dem Anruf (von unseren Zauber Stornierung Hörer) rückgängig gemacht worden. Im Allgemeinen ruft mehrmals abzubrechen ist harmlos; alle außer dem ersten Aufruf werden ignoriert.
Lassen Sie uns nun entfernen Sie die Magie I-can-Abbrechen-Zeug Zuhörer und weitermachen:
& Nbsp; >>> s2.cancel ()
& Nbsp; Wahr
Mit Non-Callables wie Rückrufe
Immer, wenn wir oben gemacht Abonnements, wir tatsächlich Simplied Dinge ein wenig. Der vollständige Signatur der Methode ist:
& Nbsp; def abonnieren (listener [, Verfahren [, reference_retention]])
Lassen Sie uns zunächst erkunden Sie die Methode Argument. Bis jetzt haben wir nur als Zuhörer verwendet Funktionsobjekte. Im Grunde genommen, in der Tat, wir könnten jede aufrufbare Objekt verwendet haben. Denken Sie daran, dass jedes Objekt ist "Callable" in Python, wenn sie eine __call__ Methode bietet, so denke, was ist der Standardwert der Methode Argument?
& Nbsp; >>> s1 = some_event.subscribe (Drucker, method = "__ call__ ')
& Nbsp; >>> some_event.publish ('foo')
& Nbsp; ('foo',) {}
& Nbsp; ('foo',) {}
& Nbsp; >>> s1.cancel ()
& Nbsp; Wahr
Nichts Neues. So, jetzt könnte man fragen: wenn ich eine andere Methode Namen verwenden?
& Nbsp; >>> class Target (Ziel):
& Nbsp; ... def __init __ (self, name):
& Nbsp; ... self.name = name
& Nbsp; ... def _callback (self, * args, ** Tasten):
& Nbsp; ... print self.name, args, Schlüssel
& Nbsp; >>> s1 = some_event.subscribe (Target ('foo'))
& Nbsp; >>> some_event.publish ('! Bumm') #doctest: + ELLIPSIS
& Nbsp; Traceback (jüngste Aufforderung zuletzt):
& Nbsp; ...
& Nbsp; Typeerror: 'Target' Objekt ist nicht aufrufbar
Oops. Lassen Sie uns nehmen Sie den Täter, bevor jemand unser Fehler bemerkt:
& Nbsp; >>> s1.cancel ()
& Nbsp; Wahr
& Nbsp; >>> s1 = some_event.subscribe (Target ('foo'), method = '_ Callback ")
& Nbsp; >>> some_event.publish (Werke! ")
& Nbsp; ('! Arbeiten',) {}
& Nbsp; foo (Werke! ",) {}
Referenz Retention
Also, das ist, dass. Es gibt immer noch ein unerforschtes Argument links abonnieren, wenn: reference_retention. Der Name klingt gefährlich, aber was tut sie?
& Nbsp; >>> Hörer = Target ('lecker')
& Nbsp; >>> s2 = some_event.subscribe (Hörer, method = '_ Rückruf', reference_retention = RR.WEAK)
& Nbsp; >>> some_event.publish ('yow')
& Nbsp; ('yow ") {}
& Nbsp; foo ('yow ") {}
& Nbsp; yummy ('yow ") {}
Hm. Bisher wurden keine Unterschiede. Lassen Sie uns eine einfache Änderung:
& Nbsp; >>> Hörer = None
& Nbsp; >>> some_event.publish ('yow')
& Nbsp; ('yow ") {}
& Nbsp; foo ('yow ") {}
Ah. Ok. Unsere yummy Zuhörer ist weg. Was ist passiert? Nun, durch die Angabe eines Bezugsaufbewahrungsrichtlinie von schwachen, gesagt, dass wir den Publisher, dass es einen schwachen Verweis auf den Listener gerade installiert verwenden, anstelle des Standard starke Referenz. Und nachdem wir veröffentlicht die einzige andere bekannte starke Verweis auf den Listener, indem Sie Hörer None, der Hörer tatsächlich vom Verleger entfernt. Beachten Sie, BTW., Dass das obige Beispiel kann mit anderen als CPython Python-Implementierungen scheitern, wegen der verschiedenen Strategien in Bezug auf Speicherbereinigung. Der Grundsatz sollte gültig bleiben kann, obwohl in Jython sowie Iron, aber in diesen Implementierungen gibt es keine Garantie, dass der Hörer wird, sobald die letzte Referenz auf sie fallengelassen wird entfernt.
Natürlich, das alles funktioniert auch, wenn die Methode aufgerufen werden soll ist die Standardeinstellung ein: __call__:
& Nbsp; >>> def make_listener (Name):
& Nbsp; ... def Hörer (* args, ** Tasten):
& Nbsp; ... print name, args, Schlüssel
& Nbsp; ... Rückkehr Zuhörer
& Nbsp; >>> Hörer = make_listener ("schwach")
& Nbsp; >>> s2 = some_event.subscribe (Hörer, reference_retention = RR.WEAK)
& Nbsp; >>> some_event.publish ("Ereignis")
& Nbsp; ("Ereignis",) {}
& Nbsp; foo ("Ereignis",) {}
& Nbsp; schwach ("Ereignis",) {}
& Nbsp; >>> Hörer = None
& Nbsp; >>> some_event.publish ("Ereignis")
& Nbsp; ("Ereignis",) {}
& Nbsp; foo ("Ereignis",) {}
Das ist alles, was man über die Bibliothek kennen. Wie ich bereits sagte: Es ist einfach, und vielleicht nicht sinnvoll für alle scenarioes und Anwendungsfälle, aber es tut, was es wurde geschrieben.
Fehlerbehandlung
Die Publisher-Klasse ist nicht für die in Unterklassen unterteilt werden. Wenn Sie das Verhalten anpassen müssen, verwenden Sie Richtlinienobjekte / Rückrufe, die an den Konstruktor übergeben werden. Gerade jetzt, es gibt einen einzigen einstellbaren Politik, nämlich das Verhalten des Herausgebers in Fall Zuhörer erhöhen Ausnahmen:
& Nbsp; >>> def Toobad (event):
& Nbsp; ... wenn Ereignis == 'raise':
& Nbsp; ... zu erhöhen Valueerror
& Nbsp; >>> s1 = some_event.subscribe (Toobad)
& Nbsp; >>> some_event.publish ("unschädlich")
& Nbsp; ("unschädlich",) {}
& Nbsp; foo ("unschädlich",) {}
& Nbsp; >>> some_event.publish ("raise")
& Nbsp; Traceback (jüngste Aufforderung zuletzt):
& Nbsp; ...
& Nbsp; Valueerror
Wie Sie sehen können, ist das Standardverhalten, wieder werfen die Ausnahme von innen zu veröffentlichen. Dies könnte nicht in Abhängigkeit von dem Anwendungsfall ausreichend sein. Insbesondere wird es keine Zuhörer später registriert, ausgeführt werden zu verhindern. So definieren wir unsere eigene Fehlerbehandlung:
& Nbsp; >>> def LOG_ERROR (Ausnahme, den Wert, Rückverfolgung, Abonnement, args, Schlüssel):
& Nbsp; ... print "gefangen", ausgenommen
& Nbsp; >>> publisher = Publisher (exception_handler = log_error)
& Nbsp; >>> publisher.subscribe (Toobad) #doctest: + ELLIPSIS
& Nbsp;
& Nbsp; >>> publisher.subscribe (Drucker) #doctest: + ELLIPSIS
& Nbsp;
& Nbsp; >>> publisher.publish ("unschädlich")
& Nbsp; ("unschädlich",) {}
& Nbsp; >>> publisher.publish ("raise")
& Nbsp; gefangen
& Nbsp; ("raise") {}
Als Alternative zur Bereitstellung der Fehlerbehandlung bei Bauzeit, können Sie auch eine Fehlerbehandlung bei der Veröffentlichung ein Ereignis, etwa so:
& Nbsp; >>> def log_error_2 (Ausnahme, den Wert, Rückverfolgung, Abonnement, args, Schlüssel):
& Nbsp; ... print "gefangen", Ausnahme ", während der Veröffentlichung"
& Nbsp; >>> publisher.publish_safely (log_error_2 "raise")
& Nbsp; gefangen während der Veröffentlichung
& Nbsp; ("raise") {}
Wie Sie sehen können, nimmt der per-Call-Fehlerhandler Vorrang vor Standard-Fehlerbehandlungsroutine des Herausgebers. Beachten Sie, dass es keine Verkettung, dh wenn die per-Call-Fehler-Handler löst eine Exception aus, Standard-Handler des Verlages nicht aufgerufen, sondern die Ausnahme wird einfach außen an den Aufrufer der publish_safely propagiert: der Herausgeber hat keine Möglichkeit, zu unterscheiden zwischen Ausnahmen ausgelöst, da der Handler möchte den Versand und Ausnahmen zufällig angehoben abbrechen, so dass alle Ausnahmen vom Handler angehoben werden einfach an die Client-Anwendung weitergeleitet.
Threadsicherheit
Die Bibliothek ist voll bewusst, Gewinde und Thread-sicher. So abonnieren Sie einen Hörer in mehreren Threads gemeinsam ist sicher, und so wird Abbestellungen

Was ist neu in dieser Pressemitteilung:.

  • Abonnement übernimmt jetzt den Zugang zu ihren Listener-Objekte und Methoden-Namen. Dies wurde aus Gründen der Fehlerbehandlungscode, der Ausnahmenprotokoll und eine bessere Möglichkeit der Identifizierung der eigentlichen Listener, der Schelm ging will hinzugefügt.

Was ist neu in Version 0.2:

  • Die Fehlerbehandlung wurde geändert. Anstelle der Unterklassen der Verleger, wird der Standardausnahmehandler jetzt als Callback an den Verlag während der Bauzeit übergeben. Die Klasse Publisher wird nun als & quot dokumentiert, nicht vorgesehen ist Unterklasse & quot;.

Anforderungen :

  • Python

Kommentare zu darts.util.events

Kommentare nicht gefunden
Kommentar hinzufügen
Schalten Sie auf die Bilder!