Python Forum
asyncio documentation has been rewritten from scratch
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
asyncio documentation has been rewritten from scratch
#1
Look a lot better than before.
I have only done some quick test with asyncio,
doing so i used tutorial online and not the old documentation.

Job done bye Yury Selivanov.
New asyncio documentation.
Quote:@gvanrossum
Finally the asyncio docs are not an embarrassment to us all. Thanks
Reply
#2
Quote:
import asyncio

async def main():
    print('Hello ...')
    await asyncio.sleep(1)
    print('... World!')

# Python 3.7+
asyncio.run(main())

They added a run function, so you don't have to manually create an event loop. That's actually pretty sweet, and makes using async much easier.
Reply
#3
Ok, so after looking into this a bit more, I'm not sure the docs are actually helpful past the basics. If you think about why you're using async/await in the first place, it's so that you don't need to wait for external resources (a web request, db query, file reading) to finish before you continue working. It's so you can start something up, and while it's just waiting for a result, you can continue to work in the one thread (this isn't multithreading or multiprocessing, it's just using a single thread more efficiently), and then later, once you have to have that data to continue, you can await for that data to finish being received.

These examples are about how to use the async/await syntax to use a library written that way, but they don't help you write the library. After reading the examples, I don't feel like you'd be in a better position than if you just wrote synchronous code and ignored async/await.

The fact that a coroutine doesn't actually do anything until you use await, also means that you can't just define an async function to work that way, either.

Let's take a hypothetical example of a database (DB). You query it, and it might take a few seconds for that query to run and results to get back to you. You should be able to use that time to do something else, instead of just waiting (or if you're a gui app, your whole app freezes while waiting for data?).

So, hypothetically, we would want to do this:
async def main():
    await with DB.open() as connection:
        query = connection.query("select * from spam")

        # at this point, the query should be running on the remote server,
        # and we should be able to do something else while it does it's thing
        page_to_compare_results = requests.get("http://google.com")

        # we can no longer do anything until we have the data from the db
        # so NOW we await
        data = await query
The problem, is that you simply can't write that using async/await. But the docs don't give an example of how you COULD do that. It is possible, though, and I'll show how later. First, I'd like to show why the async/await syntax can't do that.

>>> import asyncio
>>> async def foo():
...   print("[foo] entered")
...   print("[foo] waiting a bit")
...   await asyncio.sleep(1)
...   print("[foo] done waiting")
...
>>> async def main():
...   print("[main] entered")
...   print("[main] calling foo()")
...   task = foo()
...   print("[main] foo called")
...   print("[main] awaiting foo")
...   await task
...   print("[main] await complete")
...
>>> asyncio.run(main())
[main] entered
[main] calling foo()
[main] foo called
[main] awaiting foo
[foo] entered
[foo] waiting a bit
[foo] done waiting
[main] await complete
Calling an async function does stark nothing at all (it returns a coroutine object) until you actually await it. Which means there's no setup, it doesn't start getting data, it just does nothing at all until you start waiting for it. Which means, writing code like this is not productive, and is worse than just not using async/await, as it makes your code less clear while also not providing any performance benefit.

This confused me at first, because in other languages (such as c#), calling an async function causes it to run immediately, and control flow doesn't return the the calling function until it uses await.

So if we wanted to write something that started running right away, and could later be awaited so the main thread can wait for data, we can do that using the special method __await__. But this special method cannot return a coroutine, AND it can't be async. Which means if you're chaining an async function, you need to return IT'S special __await__ coroutine. But it's possible, and works fine:
>>> import time
>>> class Spam:
...   def __init__(self):
...     print("[spam] called")
...     self.start = time.time()
...   def __await__(self):
...     print("[spam] awaited")
...     diff = time.time() - self.start
...     sleep_for = 1 - diff
...     print(f"[spam] will sleep for: {sleep_for}")
...     return asyncio.sleep(sleep_for).__await__()
...
>>> async def main():
...   print("[main] started")
...   task = Spam()
...   print("[main] after spam called")
...   await asyncio.sleep(0.25)
...   print("[main] after sleep")
...   await task
...   print("[main] after await")
...
>>> asyncio.run(main())
[main] started
[spam] called
[main] after spam called
[main] after sleep
[spam] awaited
[spam] will sleep for: 0.747551441192627
[main] after await
I just wish something like that, showing how you can actually make the bottom of the async pipeline (instead of just how to use something already in place), was somewhere in the docs.
Reply
#4
They are doing this since 2016. I hope it is more useful now. I'll look at it again.
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  NEW TO PYTHON FROM SCRATCH! WISH ME LUCK! RZola 2 2,069 Aug-16-2021, 06:02 AM
Last Post: buran
  Why do I have trouble creating code from scratch? pcsailor 6 3,885 Nov-27-2018, 10:58 PM
Last Post: nilamo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020