问题
Is it possible to do a list comprehension in Python asynchronously? I am trying to make many calls to a web api, where the bulk of the wait time is waiting for data to come back, which I would like to do asynchronously. Then after the data is fetched, I want to return the data and store it in a variable. How would I go about doing this?
Below is the non asynchronous code:
api_data = [{data_name: get_data(data_name)} for data_name in data_name_list]
Below is my attempted asynchronous solution:
async def get_api_data(data_name_list):
api_data = [{data_name: get_data(data_name)} for data_name in data_name_list]
await asyncio.wait(api_data)
await conn.close()
return api_data
data = get_api_data(data_name_list)
The problem is that the api_data
gets returned as a coroutine object
. Shouldn't it not return as a coroutine object
since I close the connection? Is there a better way to turn my non asynchronous code
into an asynchronous solution
?
回答1:
Yes, it is indeed possible to fire off multiple requests and asynchronously wait for them. Because Python is traditionally a synchronous language, you have to be very careful about what libraries you use with asynchronous Python. Any library that blocks the main thread (such as requests
) will break your entire asynchronicity. aiohttp
is a common choice for asynchronously making web API calls in Python. What you want is to create a bunch of future objects inside a Python list and await it. A future is an object that represents a value that will eventually resolve to something.
EDIT: Since the function that actually makes the API call is synchronous and blocking and you don't have control over it, you will have to run that function in a separate thread.
import asyncio
async def main():
loop = asyncio.get_event_loop()
futures = [asyncio.ensure_future(loop.run_in_executor(None, get_data, data)) for data in data_name_list]
await asyncio.gather(*futures) # wait for all the future objects to resolve
# Do something with futures
# ...
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
Please note that this is Python 3.6 code and might vary significantly from 3.7+ async code
来源:https://stackoverflow.com/questions/57263090/async-list-comprehensions-in-python