A library implements the Mediator pattern to make your code extensible.
Inspired by symfony/event-dispatcher <https://github.com/symfony/event-dispatcher>
_ component.
.. image:: https://img.shields.io/travis/Komtet/mediator.svg?style=flat-square :target: https://travis-ci.org/Komtet/mediator
Using pip:
.. code:: sh
# pip install mediator
Manually:
.. code:: sh
$ git clone https://github.com/Komtet/mediator
$ cd mediator
# python setup.py install
.. code:: python
from mediator import Mediator
m = Mediator()
.. code:: python
from mediator import Event
class EventOne(Event):
pass
class EventTwo(Event):
event_name = 'event_two'
.. code:: python
def event_listener(event):
print('Got event: %r' % event)
m.add_listener(EventOne, event_listener)
# or m.add_listener('EventOne', event_listener)
m.add_listener('event_two', event_listener)
# or m.add_listener(EventTwo, event_listener)
.. code:: python
event1 = EventOne()
event2 = EventTwo()
m.dispatch(event1)
# Got event: <EventOne object at 0x7f954bc2b250>
m.dispatch(event2)
# Got event: <EventTwo object at 0x7f954bbbd510>
.. code:: python
def another_listener(event):
print('Got another event: %r' % event)
m.add_listener(EventOne, another_listener)
m.remove_listener('EventOne', event_listener)
m.dispatch(event1)
# Got another event: <EventOne object at 0x7f954bc2b250>
.. code:: python
m.remove_listener('EventOne')
m.dispatch(event1)
# Nothing was happened
.. code:: python
m.add_listener('EventOne', another_listener, -255)
m.add_listener('EventOne', event_listener, 255)
m.dispatch(event1)
# Got another event: <EventOne object at 0x7f954bc2b250>
# Got event: <EventOne object at 0x7f954bc2b250>
.. code:: python
from mediator import SubscriberInterface
class Subscriber(SubscriberInterface):
def first(self, event):
event.first = True
def middle(self, event):
event.middle = True
def last(self, event):
event.last = True
def event2_handler(self, event):
event.success = True
def event3_handler(self, event):
event.success = True
def get_subscribed_events(self):
return {
'event1': [
['middle'],
['first', -100],
['last', 100]
],
'event2': 'event2_handler',
'event3': ['event3_handler']
}
class Event1(Event):
event_name = 'event1'
def __init__(self):
self.first = False
self.middle = False
self.last = False
class Event2(Event):
event_name = 'event2'
def __init__(self):
self.success = True
class Event3(Event2):
event_name = 'event3'
subscriber = Subscriber()
event1 = Event1()
event2 = Event2()
event3 = Event3()
m.add_subscriber(subscriber)
m.dispatch(event1)
print('%s;%s;%s' % (event1.first, event1.middle, event1.last))
# True;True;True
m.dispatch(event2)
print(event2.success)
# True
m.dispatch(event3)
print(event3.success)
# True
.. code:: python
import sys
import venusian
from mediator import VENUSIAN_CATEGORY
@SomeEvent.listen(priority=255, instance='mediator', category=VENUSIAN_CATEGORY) # All args are optional
def some_event_listener(event):
event.attr = 'value'
scanner = venusian.Scanner(mediator=mediator)
scanner.scan(package=sys.modules[__name__], categories=[VENUSIAN_CATEGORY])
m.dispatch(SomeEvent())
See source code and tests for more information.
Mediator.__init__
and Mediator.scan
now takes keyword arguments only.Mediator.set_scanner
method.Mediator.dispatch()
now takes event instances only.Mediator.add_listener
and Mediator.remove_listener
takes subclass of Event
or str
.Event.get_name()
and Event.set_name()
were removed in favor of Event.get_event_name()
and Event.event_name
class attribute.super().__init__()
in your own events.Mediator.set_scanner
method in order to allow use custom scanner instance.%Event%.listen
decorator.The MIT License (MIT)