简体   繁体   中英

Could someone explain to me why my code works? (Asyncio python)

I'm using python 3.9, so I've got my code to work, but I don't understand how the error came to be in the first place, I looked at the docs, and other answers but I didn't really understand them.

import asyncio
from selenium import webdriver

async def ToSite():
    url = "https://www.google.com"
    driver = webdriver.Firefox()
    await driver.get(url)

async def main(func):
    await func()

loop = asyncio.new_event_loop()
loop.call_soon(ToSite())
asyncio.run(asyncio.sleep(0.5))

print("hi there how are you")

This results in the following traceback and output:

hi there how are you
C:\Users\yapji\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py:667: RuntimeWarning: coroutine 'ToSite' was never awaited

I tried to await it by passing the in the main function that I made like this: loop.call_soon(main(ToSite)) This will result in the same error, as above, the only difference being instead of saying 'ToSite' was never awaited, it is replaced by 'main' was never awaited. Then I modified the main function with the return keyword like this:

async def main(func):
   return await func()

Then I passed that into loop.call_soon() again like i did in the first attempt to fix it, which will give the same error.

Then I tried this which fixed it:

import asyncio
from selenium import webdriver

async def ToSite():
    url = "https://www.google.com"
    driver = webdriver.Firefox()
    driver.get(url)

async def main(func):
    return await func()

loop = asyncio.new_event_loop()
loop.call_soon(asyncio.run(ToSite()))
print("hi there how are you")

And I have no idea why this works. I just know it does. I checked the type of asyncio.run(ToSite()) and it's a None type. So I'm not sure what's happening. I also check the type of ToSite and ToSite() the results being function at , and it is a coroutine, respectively. So I'm not sure what's going on. So could someone explain, why the error occurred and what happened when I fixed it?

The error occurred initially because you passed ToSite() to loop.call_soon() . ToSite is named poorly, because it looks like a class, but is just a function, so ToSite() calls that function and whatever it returns is passed to loop.call_soon() as a callback. It returns an awaitable, as it was defined as an async function, but nowhere is ToSite() awaited.

You then proceeded to loop.call_soon(main(ToSite)) . This changes things, because now main is called with the ToSite function as its func parameter, which is called and then awaited at the end of main by return await func() . Here, func() returns an awaitable, await awaits it and the result is returned.

However, main itself is async and will thus return an awaitable, which is never awaited - which explains the second error.

In the final example, you cut out main again (it serves no purpose) and instead call loop.call_soon(asyncio.run(ToSite())) . The awaitable returned by ToSite() is now passed to asyncio.run() - it proceeds to create and event loop and create it (as per its documentationhttps://docs.python.org/3/library/asyncio-task.html#asyncio.run )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM