Property objects can be defined on subclasses of Dispatcher to create instance attributes that emit events when their values change. Binding and unbinding works exactly the same as with events. The callback signature is slightly different however. The first two arguments will be:

  1. The instance object that generated the event
  2. The Property value


from pydispatch import Dispatcher, Property

class MyEmitter(Dispatcher):
    name = Property()
    value = Property()

class MyListener(object):
    def on_name(self, instance, value, **kwargs):
        print('emitter name is {}'.format(value))
    def on_value(self, instance, value, **kwargs):
        print('emitter value is {}'.format(value))

emitter = MyEmitter()
listener = MyListener()

emitter.bind(name=listener.on_name, value=listener.on_value) = 'foo'
# >>> emitter name is foo
emitter.value = 42
# >>> emitter value is 42

If the attribute is set to the same value, an event is not dispatched:

emitter.value = 42
# No event
emitter.value = 43
# >>> emitter value is 43

Container Properties

dict and list objects are implemented as subclasses of Property:

They will emit events when their contents change. Nesting is also supported, so even the contents of a list or dict anywhere inside of the structure can trigger an event.

from pydispatch import Dispatcher, ListProperty, DictProperty

class MyEmitter(Dispatcher):
    values = ListProperty()
    data = DictProperty()

emitter = MyEmitter()

# >>> ['foo']

emitter.values.extend(['bar', 'baz'])
# >>> ['foo', 'bar', 'baz'] = {'foo':'bar'}
# or['foo'] = 'bar'
# >>> {'foo':'bar'}['fruit'] = {'apple':'red'}['fruit']['banana'] = 'yellow'
# event would be dispatched to listeners