Skip to content

Instantly share code, notes, and snippets.

@erikbern
Last active April 3, 2022 21:35
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save erikbern/ad7615d22b700e8dbbafd8e4d2f335e1 to your computer and use it in GitHub Desktop.
Example of how to use async/await programming in Python for non-asyncio purposes
# First, let's create an awaitable object.
# In this case it's a very dumb container of integers.
# Any time a coroutine runs `await Thing(n)` it just resolves to n
# However, we could resolve it to something completely different if we wanted to
class Thing:
def __init__(self, n):
self._n = n
def __await__(self):
return (yield self)
# Simple runner of the coroutine, which ignores a bunch of
# things like error handling etc.
def thing_interceptor(coro):
value_to_send = None
while True:
try:
thing = coro.send(value_to_send)
# At this point, we assume everything we get back
# is a Thing object. But we could actually accept
# asyncio coroutines here if we wanted to, and relay
# them to the event loop. This would make it possible
# for the coroutine to use anything in asyncio
# (eg asyncio.sleep)
value_to_send = thing._n
except StopIteration as exc:
return exc.value
# This is just the standard recursive Fibonacci definition
# It serves the purpose of how you can have a deep call stack
# and still make it possible to interact back with a sort of
# "context", which in this case is a very silly thing that just
# resolves Thing(n) to n, but in theory could be something a
# lot more complex
async def f(n):
if n <= 1:
value = await Thing(n)
else:
value = await f(n-2) + await f(n-1)
return value
coro = f(10)
print(thing_interceptor(coro))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment