Mikä on hyvä ja puhdas tapahtumavetoinen ohjelmointi Pythonissa? Minulla on tällä hetkellä kokemusta siitä, mitä kutsutaan takaisinsoittohelvekseksi ' ja haluat tietää, miten se tehdään oikein.


Paras vastaus

Yllä olevien kommenttien perusteella tässä on yleinen strategia. Tietenkin yksityiskohdilla on tietysti paljon merkitystä .

Periaatteessa sinulla on kaksi osaa.

tapahtumaobjekti tai ” julkaisija” vastaa ylläpitää luetteloa kaikista toiminnoista, jotka tulisi kutsua tapahtuman tapahtuessa. Sillä on fire() -menetelmä, joka silmukkaa luetteloa ja kutsuu kaikki toiminnot vuorotellen. Sillä pitäisi todennäköisesti olla myös menetelmiä luettelon hallitsemiseksi (funktion poistaminen luettelosta, jota ei enää tarvita).

-käsittelijät tai ” tilaajat” ovat toimintoja, joihin soitat, kun tapahtuma todella tapahtuu. Ainoa hankala bitti on, että sinun on hallittava käsittelijöiden allekirjoituksia, jotta tapahtuma voi soittaa heille tekemättä ylimääräistä itsetarkastusta.

Tässä on erittäin vähäinen esimerkki:

class Event(object):

def \_\_init\_\_(self, *args):

self.handlers = set()

self.args = args

def add(self, fn):

self.handlers.add(fn)

def remove(self, fn):

self.handlers.remove(fn)

def \_\_call\_\_(self, *args):

"""fire the event -- uses \_\_call\_\_ so we can just invoke the object directly..."""

runtime\_args = self.args + args

for each\_handler in self.handlers:

each\_handler(*runtime\_args)

class ExampleObject(object):

"""publish start and stop events"""

def \_\_init\_\_(self):

self.start = Event("started")

self.stop = Event("stopped")

def example\_handler(*args):

""" reacts to an event"""

print "example handler fired", args

fred = ExampleObject()

fred.start.add(example\_handler)

fred.stop.add(example\_handler)

fred.start()

fred.stop("optional extra arg")

Tämän pitäisi tuottaa

example handler fired ("started",)

example handler fired ("stopped", "optional extra arg")

Tärkeimmät hallintakysymykset ovat:

Poikkeusten käsittely. sinun on päätettävä, onko ohjaajan oltava poikkeuksellisen turvallinen vai ei. Jos ei, yllä oleva koodi on enemmän tai vähemmän OK, mutta jos et halua, että huono tilaaja kaataa koko ohjelman, sinun on päätettävä, kuinka selviytyä poikkeuksesta ja ”purkaa” rikkovan käsittelijän tilaus. .

Muistin hallinta. Esimerkki käyttää vain funktiota käsittelijänä; ellet poista () toimintoa, jota sinun ei tarvitse Hallitse sen käyttöikää. Haluat kuitenkin usein, että käsittelijöinä / tilaajina ovat joko soitettavat objektit tai jäsenfunktiot. Jos näin on, sinun on todennäköisesti käytettävä heikkoja viitteitä esimerkissä käytetyn naiivin joukon sijasta – muuten tapahtumankäsittelijät lopulta pitävät esineitä hengissä sen jälkeen, kun heidän olisi pitänyt pudota soveltamisalan ulkopuolelle ja ne olisi kerättävä roskiin.

Metatiedot: Esimerkki sisältää vähän metatietoja – merkkijonon, joka välitetään nimellä Event() s ilmoitetaan. Sovelluksesi saattaa tarvita enemmän tai vähemmän kuin tämä. Lisää metatietoja tarkoittaa yleensä enemmän kytkentää, mikä ei ole ihanteellista. Jos kaikilla käsittelijöilläsi on (*args, **kwargs) allekirjoitus, voit aina välittää tiedot ja päättää sitten käsittelijän tasolla, välitätkö siitä vai ei.

Hyvä viite : Tarkkailumalli Pythonissa

Esimerkki toiminnassa olevasta perusideasta: teodoksi / mGui

Vastaa

Jos menet tornadon verkkokehyksen verkkosivustolle, heillä on esimerkkisivu. Tällä sivulla on esimerkki chat-sovelluskoodista. Se on epäonnistunut lyhyt ja ymmärrettävä.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *