Forked from kaelzhang/get_event_loop vs get_running_loop.py
Created
July 22, 2022 13:11
-
-
Save h0rn3t/ef2c528ec5378d185890c600f5e5afe1 to your computer and use it in GitHub Desktop.
Show a demo the differences between Python `asyncio.get_event_loop()` and (vs) `asyncio.get_running_loop()`. And also explain the differences between `asyncio.run()` and `loop.run_until_complete()`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import asyncio | |
# Ref: https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.get_event_loop | |
# > If there is no current event loop set in the current OS thread, | |
# > the OS thread is main, and set_event_loop() has not yet been called, | |
# > asyncio will create a new event loop and set it as the current one | |
loop = asyncio.get_event_loop() | |
# So, loop2 is loop | |
loop2 = asyncio.get_event_loop() | |
print('loop is loop2: ', loop is loop2) | |
async def main( | |
loop, | |
desc: str | |
): | |
if asyncio.get_event_loop() is loop: | |
print(desc, ': match') | |
else: | |
print(desc, ': not match') | |
# Ref: https://docs.python.org/3/library/asyncio-task.html#asyncio.run | |
# > This function always creates a new event loop and closes it at the end. | |
# > It should be used as a main entry point for asyncio programs, | |
# > and should ideally only be called once. | |
asyncio.run(main(loop, 'asyncio.run')) | |
# The output is: | |
# $ asyncio.run : not match | |
# Because `asyncio.run()` does following things: | |
# - create a new event loop | |
# - set the newly-created event loop as the current event loop | |
# - run the coroutine util completed | |
# - set the current event loop as None | |
# | |
# ```python | |
# new_loop = asyncio.new_event_loop() | |
# asyncio.set_event_loop(new_loop) | |
# new_loop.run_until_complete(coro) | |
# asyncio.set_event_loop(None) | |
# loop.close() | |
# ``` | |
try: | |
asyncio.get_event_loop() | |
except Exception as e: | |
print('asyncio.get_event_loop() exception after asyncio:', e) | |
# Why? | |
loop.run_until_complete(main(loop, 'loop.run_until_complete')) | |
# The output is | |
# $ loop.run_until_complete : match | |
# As explained above, we need to set the current event loop explicitly. | |
asyncio.set_event_loop(loop) | |
asyncio.get_event_loop().run_until_complete( | |
main(loop, 'asyncio.get_event_loop().run_until_complete') | |
) | |
# The output is | |
# $ asyncio.get_event_loop().run_until_complete : match | |
# Conclusion | |
# - never use `asyncio.run()` in frameworks, or you might break the code of others | |
# - be careful by using `asyncio.run()`, or it is recommended that you manage the event loop your own |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment