darts.util.events είναι μια βιβλιοθήκη της Python που παρέχει ένα απλό αποστολέα γεγονός, παρόμοιο με το κατασκεύασμα εκδήλωση που παρέχεται από την γλώσσα C # & nbsp?. Η βιβλιοθήκη δεν έχει εξωτερικές εξαρτήσεις.
Προοριζόταν για περιπτώσεις χρήσης, όπου τα συστατικά που εκπέμπουν τα γεγονότα και τα στοιχεία που ακούτε για εκδηλώσεις συμφωνήσουν σχετικά με το είδος της εκδήλωσης και τη σημασιολογία που συνδέονται με αυτό. Αυτό ισχύει, για παράδειγμα, για χειρισμού συμβάντων, που ακούει στο "κλικ" γεγονότα που σηματοδοτείται από αντικείμενα πλήκτρο GUI, ή κοινοποιήσεις που σηματοδοτείται από αντικείμενα, όταν η αξία ορισμένων αλλαγών ιδιοκτησίας. Αυτό διαφέρει από την προσέγγιση που ακολούθησε, ας πούμε, το PyDispatcher, η οποία είναι πιο γενικό, και ευνοεί την επικοινωνία μεταξύ ασθενώς συζευγμένες συστατικά.
Συμβατότητα
Ο κώδικας γράφτηκε και δοκιμαστεί με την Python 2.6. Θα πρέπει να είναι συμβατό με 2.5, καθώς, αλλά ίσως χρειαστεί να εισάγετε μερικά από __future__ γραμμές with_statement εισαγωγή εδώ και εκεί. Θα πρέπει να λειτουργεί (αυτό δεν έχει δοκιμαστεί) με εναλλακτικές υλοποιήσεις της Python όπως Jython ή IronPython. Σημειώστε, όμως, ότι ορισμένες από τις περιπτώσεις δοκιμής που ορίζονται σε αυτό το αρχείο μπορεί να αποτύχει λόγω διαφόρων εφαρμογών συλλογή σκουπιδιών? Αυτό το αρχείο γράφτηκε με CPython στο μυαλό.
Τεκμηρίωσης
Βασική χρήση
& Nbsp? >>> Από darts.lib.utils.event Εκδότης εισαγωγής, ReferenceRetention ως RR
& Nbsp? >>> Some_event = Εκδότης ()
Ο Εκδότης είναι το κύριο συστατικό. Λειτουργεί ως μητρώο για επανακλήσεις / ακροατές. Ας ορίσει έναν ακροατή
& Nbsp? >>> Εκτυπωτή def (* event_args, ** event_keys):
& Nbsp? ... Event_args εκτύπωσης, event_keys
Για να λαμβάνετε ειδοποιήσεις, οι πελάτες πρέπει να εγγραφείτε σε έναν εκδότη. Αυτό μπορεί να είναι τόσο απλό όσο
& Nbsp? >>> Some_event.subscribe (εκτυπωτή) #doctest: + ελλειπτικό
& Nbsp?
Το αποτέλεσμα της πρόσκλησης για να εγγραφείτε είναι ένα παράδειγμα (κάποια υποκατηγορία της) τάξη Συνδρομής. Η τιμή αυτή μπορεί να χρησιμοποιηθεί αργότερα, για να ακυρώσετε τη συνδρομή, όταν οι κοινοποιήσεις δεν είναι πλέον επιθυμητές. Η πραγματική υποκατηγορία είναι μια λεπτομέρεια εφαρμογής θα πρέπει κανονικά δεν νοιάζονται για. Όλα όσα πρέπει να γνωρίζετε (και έχουν τη δυνατότητα να επικαλεστεί, στην πραγματικότητα) είναι, ότι θα είναι ένα στιγμιότυπο της κλάσης Συνδρομής, και θα παράσχει ό, τι έχει καταγραφεί ως δημόσια API της κατηγορίας αυτής (αυτή τη στιγμή μόνο η μέθοδος ακυρώσετε) .
Τώρα, ας σηματοδοτήσει μια εκδήλωση και να δούμε τι συμβαίνει:
& Nbsp? >>> Some_event.publish («ένα-εκδήλωση»)
& Nbsp? («Ένα-γεγονός»,) {}
Όπως μπορείτε να δείτε, ο εκτυπωτής έχει ενημερωθεί για το συμβάν, και duefully εκτυπώνονται τα επιχειρήματά της με την κονσόλα.
Ακύρωση συνδρομές
Όπως αναφέρθηκε, το αποτέλεσμα της κλήσης εγγραφής είναι ένα ειδικό αντικείμενο της συνδρομής, η οποία αντιπροσωπεύει την εγγραφή του ακροατή με τον εκδότη.
& Nbsp? >>> S1 = some_event.subscribe (εκτυπωτή)
& Nbsp? >>> Some_event.publish («άλλο συμβάν»)
& Nbsp? ('Άλλο συμβάν »,) {}
& Nbsp? ('Άλλο συμβάν »,) {}
& Nbsp? >>> S1.cancel ()
& Nbsp? True
& Nbsp? >>> Some_event.publish («ακόμη-ακόμη-ένα»)
& Nbsp? («Ακόμη-ακόμη-ένα»,) {}
Ο εκδότης είναι πλήρως εισέχοντος. Αυτό σημαίνει, ότι μπορείτε να εγγραφείτε στα γεγονότα μέσα από έναν ακροατή, και μπορείτε να ακυρώσουν τις συνδρομές σε αυτό το πλαίσιο, καθώς και:
& Nbsp? >>> Def make_canceller (υποβρύχια):
& Nbsp? ... Def ακροατή (* unused_1, ** unused_2):
& Nbsp? ... Εκτύπωσης "Ακύρωση", subs, subs.cancel ()
& Nbsp? ... Ακροατή επιστροφή
& Nbsp? >>> S1 = some_event.subscribe (εκτυπωτή)
& Nbsp? >>> S2 = some_event.subscribe (make_canceller (S1))
& Nbsp? >>> Some_event.publish («το gotta-go») #doctest: + ελλειπτικό
& Nbsp? («Το gotta-go»,) {}
& Nbsp? («Το gotta-go»,) {}
& Nbsp? Ακύρωση
& Nbsp? >>> Some_event.publish («φύγει») #doctest: + ελλειπτικό
& Nbsp? («Φύγει»,) {}
& Nbsp? Ακύρωση
& Nbsp? >>> S1.cancel ()
& Nbsp? False
Το αποτέλεσμα της κλήσης για να ακυρώσετε μας λέει, ότι η συνδρομή είχε ήδη αναιρεθεί πριν από την κλήση (με το μαγικό ακροατή ακύρωσης μας). Σε γενικές γραμμές, ζητώντας την ακύρωση πολλές φορές είναι ακίνδυνο? όλες εκτός από την πρώτη κλήση αγνοούνται.
Ας τώρα αφαιρέσετε τη μαγεία Ι-να-να ακυρώσετε-πράγματα ακροατή και να προχωρήσουμε:
& Nbsp? >>> S2.cancel ()
& Nbsp? True
με τη χρήση μη-Callables ως callbacks
Κάθε φορά που κάναμε συνδρομές παραπάνω, μπορούμε πραγματικά simplied τα πράγματα λίγο. Η πλήρης υπογραφή της μεθόδου είναι:
& Nbsp? Def εγγραφείτε (ακροατή [, μέθοδος [, reference_retention]])
Ας εξερευνήσουμε το επιχείρημα μέθοδο πρώτο. Μέχρι τώρα, χρησιμοποιήσαμε μόνο λειτουργία αντικείμενα ως ακροατές. Βασικά, στην πραγματικότητα, θα μπορούσαμε να είχαμε χρησιμοποιήσει οποιοδήποτε απαιτητών αντικείμενο. Να θυμάστε, ότι κάθε αντικείμενο είναι «απαιτητών" σε Python, εάν παρέχει μια μέθοδο __call__, έτσι υποθέτω, αυτό που είναι η προεπιλεγμένη τιμή του ορίσματος μέθοδο;
& Nbsp? >>> S1 = some_event.subscribe (εκτυπωτής, η μέθοδος = '__ call__ »)
& Nbsp? >>> Some_event.publish ("foo")
& Nbsp? ('Foo',) {}
& Nbsp? ('Foo',) {}
& Nbsp? >>> S1.cancel ()
& Nbsp? True
Τίποτα καινούργιο. Έτσι, τώρα μπορείτε να ζητήσετε: όταν μπορώ να χρησιμοποιήσω ένα διαφορετικό όνομα μεθόδου;
& Nbsp? >>> Target κλάση (αντικείμενο):
& Nbsp? ... Def __init __ (self, όνομα):
& Nbsp? ... Self.name = όνομα
& Nbsp? ... Def _callback (self, * args, ** κλειδιά):
& Nbsp? ... Self.name εκτύπωσης, args, πλήκτρα
& Nbsp? >>> S1 = some_event.subscribe (Target ('foo'))
& Nbsp? >>> Some_event.publish (! Bumm ») #doctest: + ελλειπτικό
& Nbsp? Traceback (πιο πρόσφατη κλήση τελευταία):
& Nbsp? ...
& Nbsp? TypeError: αντικείμενο «στόχος» δεν είναι δυνατό να εξοφληθεί πρόωρα
Ωχ. Ας αφαιρέσετε το δράστη, πριν κάποιος παρατηρήσει το λάθος μας:
& Nbsp? >>> S1.cancel ()
& Nbsp? True
& Nbsp? >>> S1 = some_event.subscribe (Target (), η μέθοδος "foo" = "_ επανάκλησης»)
& Nbsp? >>> Some_event.publish («έργα!»)
& Nbsp? (! Έργων »,) {}
& Nbsp? Foo («έργα!»,) {}
Διατήρηση αναφοράς
Έτσι, αυτό είναι αυτό. Υπάρχει ακόμα ένα ανεξερεύνητο επιχείρημα να αναλάβουν δεν άφησε, όμως: reference_retention. Το όνομα ακούγεται επικίνδυνο, αλλά τι κάνει;
& Nbsp? >>> Ακροατή = Target («νόστιμη»)
& Nbsp? >>> S2 = some_event.subscribe (ακροατή, μέθοδο = "_ επανάκλησης», reference_retention = RR.WEAK)
& Nbsp? >>> Some_event.publish (YOW)
& Nbsp? (YOW »,) {}
& Nbsp? Foo (YOW »,) {}
& Nbsp? Λαχταριστά (YOW »,) {}
Χμ. Μέχρι στιγμής, δεν υπάρχουν διαφορές. Ας κάνουμε μια απλή αλλαγή:
& Nbsp? >>> Ακροατή = Κανένας
& Nbsp? >>> Some_event.publish (YOW)
& Nbsp? (YOW »,) {}
& Nbsp? Foo (YOW »,) {}
Αχ. Εντάξει. Λαχταριστά ακροατή μας έχει φύγει. Τι συνέβη? Λοιπόν, ορίζοντας μια πολιτική διατήρησης αναφοράς των αδύνατων, έχουμε πει ο εκδότης, ότι θα πρέπει να χρησιμοποιήσετε ένα αδύναμο αναφορά στον ακροατή μόλις εγκατασταθεί, αντί του προεπιλεγμένου ισχυρή αναφοράς. Και μετά θα κυκλοφορήσει τη μόνη άλλη γνωστή ισχυρή αναφορά για τον ακροατή θέτοντας ακροατή σε None, ο ακροατής έχει πράγματι αφαιρεθεί από τον εκδότη. Σημειώστε, BTW., Ότι το παραπάνω παράδειγμα μπορεί να αποτύχει με τις εφαρμογές python πλην CPython, λόγω των διαφορετικών πολιτικών σε σχέση με την συλλογή των απορριμμάτων. Η αρχή θα πρέπει να εξακολουθήσουν να ισχύουν, όμως, σε Jython καθώς IronPython, αλλά σε αυτές τις εφαρμογές, δεν υπάρχει καμία εγγύηση, ότι ο ακροατής έχει αφαιρεθεί το συντομότερο η τελευταία αναφορά για να πέσει.
Φυσικά, αυτό λειτουργεί πολύ, αν η μέθοδος που θα ονομάζεται είναι η εξ 'ορισμού: __call__:
& Nbsp? >>> Def make_listener (όνομα):
& Nbsp? ... Def ακροατή (* args, ** κλειδιά):
& Nbsp? ... Όνομα εκτύπωσης, args, πλήκτρα
& Nbsp? ... Ακροατή επιστροφή
& Nbsp? >>> Ακροατή = make_listener («αδύναμες»)
& Nbsp? >>> S2 = some_event.subscribe (ακροατή, reference_retention = RR.WEAK)
& Nbsp? >>> Some_event.publish («γεγονός»)
& Nbsp? («Γεγονός»,) {}
& Nbsp? Foo («γεγονός»,) {}
& Nbsp? Ασθενές («γεγονός»,) {}
& Nbsp? >>> Ακροατή = Κανένας
& Nbsp? >>> Some_event.publish («γεγονός»)
& Nbsp? («Γεγονός»,) {}
& Nbsp? Foo («γεγονός»,) {}
Αυτό είναι για όλα είναι εκεί για να ξέρετε για τη βιβλιοθήκη. Όπως είπα και παραπάνω: είναι απλό, και δεν θα μπορούσε να είναι χρήσιμη για όλους τους scenarioes και περιπτώσεις χρήσης, αλλά κάνει ό, τι γράφτηκε για να.
Σφάλμα χειρισμού
Η τάξη Publisher δεν πρόκειται να subclassed. Αν χρειαστεί να προσαρμόσουν τη συμπεριφορά, μπορείτε να χρησιμοποιήσετε την πολιτική αντικειμένων / callbacks, οι οποίες μεταδίδονται στον κατασκευαστή. Αυτή τη στιγμή, υπάρχει μια ενιαία ρυθμιζόμενο πολιτική, δηλαδή, η συμπεριφορά του εκδότη σε περίπτωση, οι ακροατές να αυξήσει εξαιρέσεις:
& Nbsp? >>> Def toobad (εκδήλωση):
& Nbsp? ... Αν εκδήλωση == «ρελάνς»:
& Nbsp? ... Αυξήσει ValueError
& Nbsp? >>> S1 = some_event.subscribe (toobad)
& Nbsp? >>> Some_event.publish («αβλαβές»)
& Nbsp? («Αβλαβές»,) {}
& Nbsp? Foo («αβλαβές»,) {}
& Nbsp? >>> Some_event.publish («ρελάνς»)
& Nbsp? Traceback (πιο πρόσφατη κλήση τελευταία):
& Nbsp? ...
& Nbsp? ValueError
Όπως μπορείτε να δείτε, η προεπιλεγμένη συμπεριφορά είναι να re-raise την εξαίρεση από το εσωτερικό δημοσιεύει. Αυτό μπορεί να μην είναι κατάλληλη, ανάλογα με την περίπτωση χρήσης. Ειδικότερα, θα αποτρέψει τυχόν ακροατές εγγραφεί αργότερα να τρέξει. Οπότε, ας ορίσουμε τη δική μας λάθος χειρισμό:
& Nbsp? >>> Def log_error (εξαίρεση, τιμή, traceback, συνδρομή, args, κλειδιά):
& Nbsp? ... Εκτύπωσης "πιάνεται", εξαιρουμένων
& Nbsp? >>> Εκδότη = Εκδότης (exception_handler = log_error)
& Nbsp? >>> Publisher.subscribe (toobad) #doctest: + ελλειπτικό
& Nbsp?
& Nbsp? >>> Publisher.subscribe (εκτυπωτή) #doctest: + ελλειπτικό
& Nbsp?
& Nbsp? >>> Publisher.publish («αβλαβές»)
& Nbsp? («Αβλαβές»,) {}
& Nbsp? >>> Publisher.publish («ρελάνς»)
& Nbsp? Αλιεύονται <τύπος «exceptions.ValueError»>
& Nbsp? («Ρελάνς»,) {}
Ως εναλλακτική λύση για την παροχή των χειρισμού σφαλμάτων κατά το χρόνο κατασκευής, μπορεί επίσης να δώσετε ένα πρόγραμμα χειρισμού λάθους κατά τη δημοσίευση ενός γεγονότος, όπως έτσι:
& Nbsp? >>> Def log_error_2 (εξαίρεση, τιμή, traceback, συνδρομή, args, κλειδιά):
& Nbsp? ... Εκτύπωσης "πιάνεται", αποτελεί εξαίρεση », κατά τη διάρκεια της δημοσίευσης"
& Nbsp? >>> Publisher.publish_safely (log_error_2, «ρελάνς»)
& Nbsp? Αλιεύονται <τύπος «exceptions.ValueError"> κατά τη διάρκεια της δημοσίευσης
& Nbsp? («Ρελάνς»,) {}
Όπως μπορείτε να δείτε, ο χειριστής σφάλματος ανά κλήση υπερισχύει προεπιλεγμένο πρόγραμμα χειρισμού σφαλμάτων του εκδότη. Σημειώστε, ότι δεν υπάρχει αλυσιδωτή σύνδεση, δηλαδή, αν ο χειριστής σφάλματος ανά κλήση δημιουργεί μια εξαίρεση, εξ ορισμού χειριστή του εκδότη δεν λέγεται, αλλά η εξαίρεση είναι απλά διαδίδεται προς τα έξω για να τον καλούντα publish_safely: ο εκδότης δεν έχει τρόπο να διακρίνει μεταξύ εξαιρέσεις έθεσε διότι ο χειριστής θέλει να ακυρώσετε την αποστολή και τις εξαιρέσεις που έθεσε ατύχημα, έτσι ώστε όλες οι εξαιρέσεις που έθεσε το χειριστή απλά διαβιβάζονται στην εφαρμογή πελάτη.
Ασφάλεια Θέματος
Η βιβλιοθήκη είναι πλήρως ενήμεροι νήμα και το νήμα ασφαλή. Έτσι, αποδεχόμενοι ένα ακροατή κοινά ανάμεσα σε πολλαπλά νήματα είναι ασφαλής, και έτσι ακυρώνει τις συνδρομές
Τι είναι καινούργιο σε αυτή την έκδοση:.
- Εγγραφή χειρίζεται πλέον να παρέχει πρόσβαση σε ακροατή τους αντικείμενα και τα ονόματα μέθοδο. Αυτό προστέθηκε για λόγους σφαλμάτων κώδικα χειρισμού, η οποία θέλει να συνδεθείτε εξαιρέσεις και να παρέχει έναν καλύτερο τρόπο για να εντοπιστεί η πραγματική ακροατή, ο οποίος πήγε απατεώνων.
Τι είναι καινούργιο στην έκδοση 0.2:
- Λαθών έχει αλλάξει. Αντί Οι υποκλάσεις τον εκδότη, το προεπιλεγμένο πρόγραμμα χειρισμού εξαίρεση περάσει πλέον ως επανάκλησης στον εκδότη κατά τη διάρκεια της κατασκευής. Η τάξη Εκδότης Είναι πλέον τεκμηριωμένο ως & quot? Δεν προορίζονται για να subclassed & quot?.
Απαιτήσεις :
- Python
Τα σχόλια δεν βρέθηκε