Vad är bra och ren händelsestyrd programmering i Python? Jag upplever för närvarande vad som heter ' Callback Hell ' och vill veta hur man gör det rätt.


Bästa svaret

Baserat på kommentarerna ovan är här en allmän strategi. Uppenbarligen betyder detaljerna mycket, naturligtvis .

I grund och botten kommer du att ha två delar.

händelseobjektet eller ” utgivare” ansvarar för upprätthålla en lista över alla funktioner som ska anropas när en händelse inträffar. Den har en fire() -metod som slingrar sig över listan och kallar alla funktionerna i tur och ordning. Det borde antagligen också ha metoder för att hantera listan (ta bort en funktion från listan det behövs inte längre).

hanterarna eller ” prenumeranter” är funktioner som du kommer att ringa när händelsen faktiskt inträffar. Den enda knepiga biten där är att du måste styra hanterarens signatur så att evenemanget kan ringa dem utan att göra någon extra introspektion. 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")

Det borde producera

example handler fired ("started",)

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

De viktigaste hanteringsproblemen är:

Undantagshantering. du måste bestämma om hanteraren måste vara exceptionellt säker eller inte. Om inte ovanstående kod är mer eller mindre OK, men om du inte vill att en dålig prenumerant ska få ner hela programmet måste du bestämma hur du ska hantera ett undantag och om du vill ”avprenumerera” den kränkande hanteraren eller inte. .

Minneshantering. Exemplet använder bara en funktion som hanterare, såvida du inte tar bort () den funktion du inte behöver hantera dess livstid. Men du vill ofta ha antingen anropbara objekt eller medlemsfunktioner som hanterare / prenumeranter. Om så är fallet måste du förmodligen använda svaga referenser snarare än den naiva uppsättningen som används i exemplet – annars kommer händelseshanterarna att hålla föremål levande efter att de borde ha fallit ur räckvidden och bör samlas in.

Metadata: Exemplet innehåller lite metadata – strängen som skickas in som Event() s deklareras. Din ansökan kan behöva mer eller mindre än detta. Mer metadata betyder vanligtvis mer koppling, vilket inte är perfekt. Men om dina hanterare har (*args, **kwargs) signatur kan du alltid skicka data och sedan bestämma på hanterarnivå om du bryr dig om det eller inte.

Bra referens : Observatormönstret i Python

Exempel på grundidén i aktion: theodox / mGui

Svar

Om du går till webbplatsen för tornado webbramar har de en exempelsida. På den sidan finns ett exempel på applikationskod för chatt. Det är felaktigt kort och förståeligt.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *