How to do it...

  1. Define the function:
        def cor():
hi = yield "Hello"
yield hi
  1. Create an instance:
        cor = cor()
  1. Use next() to process the function:
        print(next(cor))
  1. Use send() to provide an input value to the function:
        print(cor.send("World"))
  1. This is what it looks like put together:
  1. To make life easier and avoid having to manually call next() every time, coroutine_decorator.py shows how a decorator can be made to handle the iteration for us:
        def coroutine(funct):
def wrapper(*args, **kwargs):
cor = funct(*args, **kwargs)
next(cor)
return cor
return wrapper

According to the official documentation (https://docs.python.org/3/library/asyncio-task.html#coroutines), it is preferable to use @asyncio.coroutine to decorate generator-based coroutines. It isn't strictly enforced, but it enables compatibility with async def coroutines and also serves as documentation.

  1. asyncio_concurrent.py, from https://docs.python.org/3/library/asyncio-task.html#example-chain-coroutines, shows how to use asyncio to perform concurrent processing:
        import asyncio

async def compute(x, y):
print("Compute %s + %s ..." % (x, y))
await asyncio.sleep(1.0)
return x + y

async def print_sum(x, y):
result = await compute(x, y)
print("%s + %s = %s" % (x, y, result))

loop = asyncio.get_event_loop()
loop.run_until_complete(print_sum(1, 2))
loop.close()
    • The event loop is started (get_event_loop()) and calls print_sum()
    • The  print_sum() coroutine is suspended while it calls compute()
    • The compute() coroutine starts but immediately goes to sleep for 1 second
    • When compute() restarts, it finishes its computation and returns the result
    • The print_sum() coroutine receives the result and prints it
    • There are no more computations to perform so the print_sum() coroutine raises the StopIteration exception
    • The exception causes the event loop to terminate and the loop is closed
  1. Here is asyncio_multi_jobs.py (https://docs.python.org/3/library/asyncio-task.html#example-parallel-execution-of-tasks) that shows a better illustration of the concurrent execution of multiple jobs:
        import asyncio

async def factorial(name, number):
f = 1
for i in range(2, number+1):
print("Task %s: Compute factorial(%s)..." % (name, i))
await asyncio.sleep(1)
f *= i
print("Task %s: factorial(%s) = %s" % (name, number, f))

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(
factorial("A", 2),
factorial("B", 3),
factorial("C", 4),
))
loop.close()

In this example, three factorial coroutines are created. Because of the asynchronous nature of the code, they aren't necessarily started in order, nor are they processed and completed in order.

  1. Your results may vary, but here is an example of the output of this code:

As can be seen, the jobs were started in reverse order; if you look at the official documentation, they were started in order. Each task was completed at a different time so, while the results are in order, each individual task took a varying amount of time. This can also be seen when compared to the official documentation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset