darts.util.events is 'n Python biblioteek wat 'n eenvoudige geval planner, soortgelyk aan die geval konstruk wat deur die C # taal bied. & Nbsp; Die biblioteek het geen eksterne afhanklikhede.
Dit is bedoel vir gebruik gevalle, waar die komponente afgee gebeure en die komponente te luister vir gebeure saamstem oor die aard van die byeenkoms en die semantiek wat verband hou met dit. Dit is waar, byvoorbeeld, vir event handlers, wat op luister "klik" gebeure te kenne gegee deur GUI knoppie voorwerpe, of kennisgewings te kenne gegee deur voorwerpe, wanneer die waarde van 'n paar veranderinge eiendom. Dit verskil van die benadering wat deur, sê, die PyDispatcher, wat meer generiese en bevoordeel kommunikasie tussen swak gekoppelde komponente.
Verenigbaarheid
Die kode is geskryf vir en getoets met Python 2,6. Dit moet versoenbaar is met 2,5 wees as goed, maar jy kan 'n paar te voeg van __future__ invoer with_statement lyne hier en daar. Dit behoort te werk (dit is nog nie getoets) met alternatiewe implementering van 'n afgestorwene soos Jython of IronPython. Let egter dat sommige van die toets gevalle omskryf in hierdie lêer kan misluk as gevolg van verskillende vullisverwydering implementering; hierdie lêer is met CPython geskryf in gedagte.
Dokumentasie
Basiese Gebruik
& Nbsp; >>> van darts.lib.utils.event invoer uitgewer, ReferenceRetention as RR
& Nbsp; >>> some_event = Uitgewer ()
Die uitgewer is die belangrikste komponent. Dit dien as register vir verifikasie / luisteraars. Kom ons definieer 'n luisteraar
& Nbsp; >>> def drukker (* event_args, ** event_keys):
& Nbsp; ... druk event_args, event_keys
Ten einde te ontvang, moet kliënte inteken op 'n uitgewer. Dit kan so eenvoudig soos wees
& Nbsp; >>> some_event.subscribe (drukker) #doctest: + beletselteken
& Nbsp;
Die uitslag van die oproep om in te skryf is 'n voorbeeld van (sommige subklas van) die klas Inskrywing. Hierdie waarde kan later gebruik word, ten einde die inskrywing kanselleer wanneer kennisgewings is nie meer verlang. Die werklike subklas is 'n implementering detail wat jy moet normaalweg nie omgee. Al wat jy nodig het om te weet (en word toegelaat om te vertrou op, in werklikheid) is, dat dit 'n geval van Klas Inskrywing sal wees, en dit sal voorsien wat is gedokumenteer as openbare API van daardie klas (nou: enigste metode te kanselleer) .
Nou, laat ons sein 'n gebeurtenis en kyk wat gebeur:
& Nbsp; >>> some_event.publish ('n gebeurtenis ')
& Nbsp; ('n gebeurtenis,) {}
Soos jy kan sien, het die drukker in kennis gestel is van die gebeurtenis, en duefully gedruk die sy argumente om die konsole.
Kanselleer inskrywing
Soos genoem, is die resultaat van die roeping skryf is 'n spesiale inskrywing voorwerp, wat die registrasie van die luisteraar met die uitgewer verteenwoordig.
& Nbsp; >>> s1 = some_event.subscribe (drukker)
& Nbsp; >>> some_event.publish ('n ander gebeurtenis ')
& Nbsp; ('n ander gebeurtenis,) {}
& Nbsp; ('n ander gebeurtenis,) {}
& Nbsp; >>> s1.cancel ()
& Nbsp; True
& Nbsp; >>> some_event.publish ('n ander nog-vir-een)
& Nbsp; ('n ander nog-vir-een en) {}
Die uitgewer is ten volle weer deelnemer. Dit beteken dat jy kan inteken op die gebeure van binne 'n luisteraar, en jy kan subskripsies in daardie konteks sowel kanselleer:
& Nbsp; >>> def make_canceller (subs):
& Nbsp; ... def luisteraar (* unused_1, ** unused_2):
& Nbsp; ... Druk "Kanselleer", subs, subs.cancel ()
& Nbsp; ... terugkeer luisteraar
& Nbsp; >>> s1 = some_event.subscribe (drukker)
& Nbsp; >>> s2 = some_event.subscribe (make_canceller (S1))
& Nbsp; >>> some_event.publish ('gotta-go') #doctest: + beletselteken
& Nbsp; ('gotta-go',) {}
& Nbsp; ('gotta-go',) {}
& Nbsp; Kanselleer
& Nbsp; >>> some_event.publish ('weg') #doctest: + beletselteken
& Nbsp; ('weg',) {}
& Nbsp; Kanselleer
& Nbsp; >>> s1.cancel ()
& Nbsp; Vals
Die uitslag van die oproep te kanselleer vertel ons dat die inskrywing reeds gister voor die oproep (deur ons magic kansellasie luisteraar) ongedaan gemaak. Oor die algemeen, 'n beroep te kanselleer verskeie kere skadeloos; almal, maar die eerste oproep geïgnoreer.
Kom ons verwyder nou die magic I-kan-kanselleer-stuff luisteraar en skuif op:
& Nbsp; >>> s2.cancel ()
& Nbsp; True
Gebruik Nie-Callables as verifikasie
Wanneer ons het bo subskripsies, het ons eintlik simplied dinge 'n bietjie. Die volle handtekening van die metode is:
& Nbsp; def skryf (luisteraar [, metode [, reference_retention]])
Kom ons die metode argument eerste verken. Tot nou toe het ons net gebruik funksie voorwerpe as luisteraars. Basies, in werklikheid, het ons dalk 'n call able voorwerp gebruik. Onthou, dat enige voorwerp is "call able" in Python, as dit bied 'n __call__ metode, so dink, wat is die standaard waarde van die metode argument?
& Nbsp; >>> s1 = some_event.subscribe (drukker, metode = '__ call__')
& Nbsp; >>> some_event.publish ('cat')
& Nbsp; ('cat') {}
& Nbsp; ('cat') {}
& Nbsp; >>> s1.cancel ()
& Nbsp; True
Niks nuuts nie. So, nou kan jy vra: wanneer ek 'n ander metode naam te gebruik?
& Nbsp; >>> klas Target (voorwerp):
& Nbsp; ... def __init __ (self, naam):
& Nbsp; ... self.name = naam
& Nbsp; ... def _callback (self, * argumente, ** sleutels):
& Nbsp; ... druk self.name, argumente, sleutels
& Nbsp; >>> s1 = some_event.subscribe (Target ('cat'))
& Nbsp; >>> some_event.publish ('! Bumm') #doctest: + beletselteken
& Nbsp; Stapelspoor (mees onlangse oproep laaste):
& Nbsp; ...
& Nbsp; TypeError: "Target" voorwerp is nie call able
Oops. Kom ons verwyder die oortreder, voordat iemand kennisgewings ons fout:
& Nbsp; >>> s1.cancel ()
& Nbsp; True
& Nbsp; >>> s1 = some_event.subscribe (Target ('cat'), metode = '_ terugbel')
& Nbsp; >>> some_event.publish (se werke! ")
& Nbsp; ('! Werke,) {}
& Nbsp; cat (se werke! ",) {}
Reference Behoud
So, dit is dit. Daar is nog 'n onbekende argument in te skryf gelaat, maar: reference_retention. Die naam klink gevaarlik, maar wat doen dit?
& Nbsp; >>> luisteraar = Target ('n lekker ')
& Nbsp; >>> s2 = some_event.subscribe (luisteraar, metode = '_ terugbel, reference_retention = RR.WEAK)
& Nbsp; >>> some_event.publish ('jou')
& Nbsp; ('jou',) {}
& Nbsp; cat ('jou',) {}
& Nbsp; yummy ('jou',) {}
Hm. Tot dusver geen verskille. Kom ons maak 'n eenvoudige verandering:
& Nbsp; >>> luisteraar = Geen
& Nbsp; >>> some_event.publish ('jou')
& Nbsp; ('jou',) {}
& Nbsp; cat ('jou',) {}
Ag. Ok. Ons lekker luisteraar is weg. Wat het gebeur? Wel, deur die spesifiseer 'n verwysing behoud beleid van swak, het ons die uitgewer, dat dit 'n swak verwysing na die luisteraar net geïnstalleer moet gebruik, in plaas van die standaard sterk verwysing. En nadat ons vrygestel die enigste ander bekende sterk verwysing na die luisteraar deur die oprigting luisteraar Geen, was die luisteraar eintlik verwyder van die uitgewer. Let wel, BTW., Dat die bogenoemde voorbeeld kan misluk met ander as CPython python implementering, te danke aan die verskillende beleide met betrekking tot vullisverwydering. Die beginsel moet geldig bly, al is, in Jython asook IronPython, maar in daardie implementering, daar is geen waarborg dat die luisteraar so gou as die laaste verwysing na dit gedaal verwyder word.
Natuurlik, al hierdie werk ook as die metode genoem te word is die standaard een: __call__:
& Nbsp; >>> def make_listener (naam):
& Nbsp; ... def luisteraar (* argumente, ** sleutels):
& Nbsp; ... naam druk, argumente, sleutels
& Nbsp; ... terugkeer luisteraar
& Nbsp; >>> luisteraar = make_listener ('swak ")
& Nbsp; >>> s2 = some_event.subscribe (luisteraar, reference_retention = RR.WEAK)
& Nbsp; >>> some_event.publish ('event')
& Nbsp; ('event') {}
& Nbsp; cat ('event') {}
& Nbsp; swak ('event') {}
& Nbsp; >>> luisteraar = Geen
& Nbsp; >>> some_event.publish ('event')
& Nbsp; ('event') {}
& Nbsp; cat ('event') {}
Dit is omtrent al wat daar is om te weet oor die biblioteek. Soos ek hierbo gesê het: Dit is eenvoudig, en kan nie nuttig vir alle scenarioes en gebruik gevalle, maar dit doen wat dit geskryf is.
Fout hantering
Die uitgewer klas is nie bedoel om subclassed. As jy nodig het om die gedrag maat, beleid voorwerpe / verifikasie, wat geslaag om die constructor gebruik jy. Nou, is daar 'n enkele verstelbare beleid, naamlik, die gedrag van die uitgewer in die geval, die luisteraars te samel uitsonderings:
& Nbsp; >>> def toobad (event):
& Nbsp; ... as geval == 'n verhoog ':
& Nbsp; ... samel ValueError
& Nbsp; >>> s1 = some_event.subscribe (toobad)
& Nbsp; >>> some_event.publish ('onskuldig')
& Nbsp; ('onskuldig',) {}
& Nbsp; cat ('onskuldig',) {}
& Nbsp; >>> some_event.publish ('n verhoog ')
& Nbsp; Stapelspoor (mees onlangse oproep laaste):
& Nbsp; ...
& Nbsp; ValueError
Soos jy kan sien, die standaard gedrag is om weer in te samel die uitsondering van binne te publiseer. Dit kan nie voldoende wees nie, afhangende van die gebruik geval. In die besonder, sal dit verhoed dat enige luisteraars later geregistreer om te loop nie. So, kom ons definieer ons eie fout hantering:
& Nbsp; >>> def log_error (uitsondering, waarde, Stapelspoor, inskrywing, argumente, sleutels):
& Nbsp; ... Druk "gevang", uitsondering
& Nbsp; >>> uitgewer = Uitgewer (exception_handler = log_error)
& Nbsp; >>> publisher.subscribe (toobad) #doctest: + beletselteken
& Nbsp;
& Nbsp; >>> publisher.subscribe (drukker) #doctest: + beletselteken
& Nbsp;
& Nbsp; >>> publisher.publish ('onskuldig')
& Nbsp; ('onskuldig',) {}
& Nbsp; >>> publisher.publish ('n verhoog ')
& Nbsp; gevang
& Nbsp; ('n verhoog,) {}
As 'n alternatief vir die verskaffing van die fout hanteerder by die konstruksie van tyd, kan jy ook 'n fout hanteerder wanneer publikasie van 'n gebeurtenis, soos so:
& Nbsp; >>> def log_error_2 (uitsondering, waarde, Stapelspoor, inskrywing, argumente, sleutels):
& Nbsp; ... Druk "gevang", uitsondering, "tydens publikasie"
& Nbsp; >>> publisher.publish_safely (log_error_2, "verhoog ')
& Nbsp; gevang
& Nbsp; ('n verhoog,) {}
Soos jy kan sien, die per-call fout hanteerder neem voorkeur oor die uitgewer se verstek fout hanteerder. Let wel, dat daar geen skakeling, dit wil sê, as die per-call fout hanteerder verhoog 'n uitsondering, is die uitgewer se verstek hanteerder nie genoem nie, maar die uitsondering is eenvoudig buite gepropageer aan die oproeper van publish_safely: die uitgewer het geen manier om te onderskei tussen uitsonderings opgewek omdat die hanteerder wil die versending en uitsonderings wat deur 'n ongeluk te staak, so al uitsonderings wat deur die hanteerder is eenvoudig gestuur na die kliënt aansoek.
Draad Veiligheid
Die biblioteek is ten volle bewus ryg en ryg veilig. Dus, 'n inskrywing op 'n luisteraar gedeel oor verskeie drade is veilig, en so is die kansellasie van Subskripsies
Wat is nuut in hierdie release:.
- Inskrywing hanteer nou toegang tot hul luisteraar voorwerpe en metode name. Dit is bygevoeg ter wille van die fout hantering kode, wat wil uitsonderings aanmeld en 'n beter manier van die identifisering van die werklike luisteraar, wat skelm het.
Wat is nuut in weergawe 0.2:
- het Fout hantering verander. In plaas van subclassing die uitgewer, is die standaard uitsondering hanteerder nou verby as terugbel aan die uitgewer tydens konstruksie. Die klas Uitgewer nou gedokumenteer as & quot; nie bedoel vir die feit dat subclassed & quot;.
Vereistes :
- Python
Kommentaar nie gevind