В настоящее время я много раз вызываю внешний API и загружаю содержимое ответа при каждом вызове. Я использую aiohttp и asyncio, чтобы ускорить этот процесс, но не могу понять, как отделить функции выборки от функций сохранения.
import asyncio
import os
from aiohttp import ClientSession
В настоящее время я использую следующую функцию:
async def fetch_and_save(link, path, client):
async with await client.get(link) as response:
contents = await response.read()
if not os.path.exists(os.path.dirname(path)):
os.makedirs(os.path.dirname(path))
with open(path, "wb") as f:
f.write(contents)
Мой основной вызов выглядит так:
async def fetch_and_save_all(inputs):
async with ClientSession() as client:
tasks = [asyncio.ensure_future(fetch_and_save(link, path, client))
for link, path in inputs]
for f in asyncio.as_completed(tasks):
await f
def main(inputs):
loop = asyncio.get_event_loop()
loop.run_until_complete(fetch_and_save_all(inputs))
if __name__ == "__main__":
inputs = [
(f"https://httpbin.org/range/{i}", f"./tmp/{i}.txt") for i in range(1, 10)]
main(inputs)
Учитывая этот базовый пример, возможно ли разделить функции извлечения и сохранения в fetch_and_save
?
@sytech Мне действительно трудно издеваться над извлечением, и я думаю, что сохранение усложняет процесс.
Я понимаю. Разве простое перемещение соответствующего кода для извлечения и сохранения в их собственные функции не решит эту проблему? например fetch_and_save
сделал бы что-то вроде await save(await fetch(...))
Тогда соответствующие функции могут быть смоделированы независимо.
Просто создайте независимые функции для fetch
порции и save
порции.
async def fetch(link, client):
async with await client.get(link) as response:
contents = await response.read()
return contents
def save(contents, path):
if not os.path.exists(os.path.dirname(path)):
os.makedirs(os.path.dirname(path))
with open(path, 'wb') as f:
bytes_written = f.write(contents)
return bytes_written
async def fetch_and_save(link, path, client):
contents = await fetch(link, client)
save(contents, path)
Что именно вы имеете в виду под словом "отдельный"? Каков желаемый конечный результат или интерфейс? Конечно, можно просто вынести код сохранения в отдельную функцию, но я не думаю, что вы имеете в виду это.