This kind of functionality is usually called Signals or Single dispatcher in the Python community.
Signals are widely used in modern Python projects/libraries to reduce coupling, but there's no implementation in the Python standard(the signal module can only catch some os signals, it is not designed for general usage). So different projects may implement their own signal system(e.g PyQt) or use a third-party signal/single dispatcher library(e.g Flask, Django). If you are using a Python framework, it is likely that the framework already had a signal system.
People today usually use PyDispatcher(used by Django), or Blinker(used by Flask). They both have high code quality and good documentation. I prefer Blinker personally.
blinker example:
def subscriber(sender):
print("Got a signal sent by %r" % sender)
ready = signal('ready')
ready.connect(subscriber)
class Processor:
def __init__(self, name):
self.name = name
def go(self):
ready = signal('ready')
ready.send(self)
print("Processing.")
complete = signal('complete')
complete.send(self)
def __repr__(self):
return '<Processor %s>' % self.name
processor_a = Processor('a')
processor_a.go()
Output:
Got a signal sent by <Processor a>
Processing.