Python Asyncio Coroutine vs Subroutine
Links:
- 108 Python Index
- Python - Asyncio
Coroutine vs Subroutines¶
- Subroutine calling model:
- Each time a function is called execution moves to the start of that function then continues until it reaches the end of that function (or a
return
statement) - At this point execution moves back to the point immediately after the function call, any later calls to the function are independent calls which start again at the beginning.
- Each time a function is called execution moves to the start of that function then continues until it reaches the end of that function (or a
- Coroutine calling model:
- In this model there is a new way for the method (called a coroutine) to move execution back to the caller: instead of returning it can
yield
control. - When the coroutine "yields" execution moves back to the point immediately after it was called, but future calls to the coroutine do not start again at the beginning, instead they continue from where the execution left off most recently.
- This way control can bounce back and forth between the calling code and the coroutine code.
- In this model there is a new way for the method (called a coroutine) to move execution back to the caller: instead of returning it can
-
Subroutine vs coroutine
-
Code example:
def some_function(): print("yielding 5") yield 5 print("yielding 10") yield 10 print("returning 15") # return just raises a stop iteration excpetion return 15 call = some_function() print(call) # unless and until you call next() generator function won't be executed # We call next on the same generator object to return the next item of the iterator value1 = next(call) print(value1) value2 = next(call) print(value2) value3 = next(call) # OUTPUT: # <generator object some_function at 0x10129fd10> # yielding 5 # 5 # yielding 10 # 10 # returning 15 # Traceback (most recent call last): # File "/Users/sarthaknarayan/Desktop/testfolder/coroutines.py", line 20, in <module> # value3 = next(call) # StopIteration: 15 # this piece of code won't stop code execution since for loop knows how to handle StopIteration exception # for i in call: # print(i)
- Notice that
return
just raises aStopIteration
exception in the generator with the return value as the exception message.- Ideally return statements are used to terminate generators with a if clause.
def geometric_progression(a, q):
k = 0
while True:
result = a * q**k
if result <= 100000:
yield result
else:
return
k += 1
for n in geometric_progression(2,5):
print(n)
- Python has had the capability to allow this execution model for some time in the form of Generators.
- But asyncio adds a new type of coroutine, which allows a natural way to write code where execution can move around between coroutines when the current one gets blocked.
Last updated: 2022-11-11