[Python-ideas] How the heck does async/await work in Python 3.5

Terry Reedy tjreedy at udel.edu
Tue Feb 23 21:37:12 EST 2016


On 2/23/2016 4:25 PM, Joao S. O. Bueno wrote:
> Today I also stumbled on this helpful "essay" from Brett Cannon about
> the same subject
>
> http://www.snarky.ca/how-the-heck-does-async-await-work-in-python-3-5

In this essay, Brett says that asyncio added an event loop to Python. 
It did, but it was the second.  The tk event loop was added about 20 
years ago with tkinter.  He also said that this enabled asynchronous 
programming to Python.  It actually added async i/o to go along with 
async key-mouse-screen user interface.  To illustrate, Brett gives this 
example, which only uses screen output.

import asyncio

# Borrowed from http://curio.readthedocs.org/en/latest/tutorial.html.
@asyncio.coroutine
def countdown(number, n):
     while n > 0:
         print('T-minus', n, '({})'.format(number))
         yield from asyncio.sleep(1)
         n -= 1

loop = asyncio.get_event_loop()
tasks = [
     asyncio.ensure_future(countdown("A", 2)),
     asyncio.ensure_future(countdown("B", 3))]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

It outputs 2 or 1 lines at 1 second intervals.

T-minus 2 (A)
T-minus 3 (B)
T-minus 1 (A)
T-minus 2 (B)
T-minus 1 (B)

and stops after 2 seconds.

The tkinter equivalent

import tkinter
root = tkinter.Tk()
#root.withdraw()  # optionally hide the window

def countdown(number, n):
     if n > 0:
         print('T-minus', n, '({})'.format(number))
         n -= 1
         root.after(1000, countdown, number, n)

root.after(1, countdown, 'A', 2)
root.after(1, countdown, 'B', 3)
root.mainloop()

has the same output, but needs either the window close button [X] or 
other means to stop.  (Tk mainloop() is equivalent to asyncio 
loop.run_forever()) Of course, in normal use, the output would go to a 
widget in the window, so having the window is not a problem.

It would be nice to be able to use a repeatedly resumed generator 
instead of a repeatedly called callback with tkinter .after also.  I am 
thinking about how that might be done.  Maybe a generic callback that 
calls next(generator) when called.  I may also look as Brett's example 
of interfacing with async and await keywords.

-- 
Terry Jan Reedy



More information about the Python-ideas mailing list