Using generators on Observable class I've decided to implement a simple case of the Observer pattern. I've gone about this considering you can only register 1 single observer in the Observable, instead of allowing multiple ones. 

I would really like feedback about what'd be the proper way to return the listener in the run method while still yielding values, if possible i'd like to allow some sort of method chaining

Overall I would like some criticism about this whole design and of course, anything else is on the table will be appreciated.

Code:

import time


class Observer:

    def __init__(self):
        self.lines = []
        self.execution_time = None

    def on_process(self, value):
        line = f"&lt;&lt; processed: {value} &gt;&gt;"
        self.lines.append(line)
        return line

    def on_done(self, value):
        self.execution_time = value


class Observable:

    def __init__(self):
        self.listener = None

    def register_listener(self, listener):
        self.listener = listener
        return self

    def run(self, iterable):
        s = time.time()
        for v in iterable:
            yield self.listener.on_process(v)

        self.listener.on_done(time.time() - s)


if __name__ == '__main__':
    obj = Observable().register_listener(Observer())

    for x in obj.run(range(10)):
        print(x)

    listener = obj.listener
    print("Number of lines:", len(listener.lines))
    print("Execution time:", listener.execution_time)
You haven't implemented the observer pattern as your subject, Observable, doesn't contain a list of observers.

Whilst this may seem like some small petty point it is the core problem that the pattern hopes to solve.
You have failed to make the subject relay to its observers. As you have moved the code, run, that should be in the observer into the subject.

This makes the observer interface neigh on useless, because if you want to change this functionality then you're screwed.


An example of the observer pattern is in Python's logging library.
In this you have events like a logger.info(message).
The logger, the subject, goes on to call the underlying handlers, observers, with the event.
This causes the handler to handle the event how it's been designed to.

It's common to have a StreamHandler and sometimes a FileHandler.
The former that just prints the message, and the latter that writes the message to a file.