Step 1 - Coroutine Concept

To explain the concept in full detail let us look at standard function calls again.

def function():
    # do something
    return # some value

def other_function():
    # do something else
    return # another value

some_value = function()
another_value = other_function()

As a sequence diagram:

sequenceDiagram participant c as Caller participant f1 as Function participant f2 as Other Function activate c activate c c->>f1: call deactivate c activate f1 f1->>c: return deactivate f1 activate c c->>f2: call deactivate c activate f2 f2->>c: return deactivate f2 deactivate c

All function calls are run in a sequence. The caller must wait until the function is finished to execute its next code, for example another function call.

Besides let us take a look at Generators/Iterators.

def generator():
    # do something
    yield # something
    # do something else
    yield # something else
    # do another thing
    return # some value

def function():
    # do something
    return # a value


gen = generator()
next(gen)
next(gen)
a_value = function()
try:
    next(gen)
except StopIteration as e:
    some_value = e.value

Also as a sequence diagram:

sequenceDiagram participant c as Caller participant g as Generator participant f as Function activate c activate c c->>g: next deactivate c activate g activate g g-->>c: yield deactivate g activate c c->>g: next deactivate c activate g g-->>c: yield deactivate g activate c c->>f: call deactivate c activate f f->>c: return deactivate f activate c c->>g: next deactivate c activate g g->>c: return/StopIteration deactivate g deactivate g deactivate c

A Generator can yield values to the caller during its execution. The caller can request the next value from the Generator and do other things in between for example calling a function.

Summary

  • Calling a function blocks the caller until the function returns.

  • A Generator can give control back to the caller.

  • The caller can do other things after getting in control again like calling another function.

  • The caller can resume the Generator.

  • The caller doesn’t need to be interested in the yielded values.

  • A Generator can return a final value just like a normal function.

  • A Generator is a coroutine.

Note

When mentioning the term coroutine in the following steps of this chapter, it references a Python generator function or generator object.