Legjobb válasz
A fenti megjegyzések alapján itt az általános stratégia. Természetesen a részletek természetesen sokat számítanak .
Alapvetően két részből áll.
A eseményobjektum vagy a “ megjelenítő” felelős azoknak a funkcióknak a listája, amelyeket meg kell hívni, amikor egy esemény bekövetkezik. Van egy fire()
metódusa, amely hurokba lép a listán, és az összes függvényt egymás után hívja meg. Valószínűleg rendelkeznie kell módszerekkel a lista kezelésére (egy olyan funkció eltávolítása a listából, amelyre már nincs szükség).
A kezelők vagy a “ előfizetők” olyan funkciók, amelyeket akkor fogsz hívni, amikor az esemény valóban megtörténik. Az egyetlen trükkös dolog az, hogy ellenőriznie kell a kezelők aláírását, hogy az esemény minden további önvizsgálat nélkül felhívhassa őket.
Itt egy nagyon minimális példa:
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")
Ennek létre kell hoznia
example handler fired ("started",)
example handler fired ("stopped", "optional extra arg")
A fő kezelési problémák a következők:
Kivételek kezelése. el kell döntenie, hogy a kezelőnek kivételesen biztonságosnak kell-e lennie vagy sem. Ha nem, akkor a fenti kód nagyjából rendben van, de ha nem akarja, hogy egy rossz előfizető lerombolja az egész programot, akkor el kell döntenie, hogyan kell kezelni a kivételt, és hogy “el kell-e iratkozni” a vétkes kezelőről. .
kezelje az élettartamát. Azonban gyakran azt szeretné, hogy hívható objektumok vagy tagfunkciók legyenek kezelőként / előfizetőként. Ha igen, akkor valószínűleg gyenge referenciákat kell használnia a példában használt naiv halmaz helyett – különben az eseménykezelők végül életben tartják az objektumokat, miután ki kellett volna esniük a hatókörből, és szemetet kell gyűjteniük.
Metaadatok: A példa tartalmaz egy kis metaadatot – a karakterláncot, amelyet Event()
s vannak deklarálva. Alkalmazásához ennél többre vagy kevesebbre lehet szükség. A több metaadat általában több összekapcsolást jelent, ami nem ideális. Ha azonban az összes kezelője rendelkezik a (*args, **kwargs)
aláírással, akkor mindig átadhatja az adatokat, majd a kezelő szintjén eldöntheti, hogy törődik-e velük vagy sem.
Jó referencia : A megfigyelő minta a Pythonban
Példa az alapötletre a műveletben: theodox / mGui
Válasz
Ha felkeresi a tornádó webes keretrendszer webhelyét, van egy példa oldaluk. Ezen az oldalon található egy példa a csevegőalkalmazás kódjára. Ez hibásan rövid és érthető.