Майстерня асинхронності: Глибоке занурення в asyncio в Python
Дізнайтеся, як прискорити ваші Python-програми за допомогою асинхронного програмування та бібліотеки asyncio. Практичні приклади та пояснення для початківців та досвідчених розробників.
У сучасному світі розробки програмного забезпечення швидкість та ефективність є ключовими. Користувачі не люблять чекати, а сервери мають обробляти тисячі запитів одночасно. Коли ваша програма витрачає більшість часу на очікування відповіді від мережі, бази даних чи файлової системи, традиційний синхронний підхід стає вузьким місцем. Саме тут на допомогу приходить асинхронне програмування. Ця стаття — ваш путівник у світ
asyncio, стандартної бібліотеки Python для написання асинхронного коду. Ми розберемося з основними концепціями, порівняємо синхронний та асинхронний підходи на реальному прикладі та покажемо, як зробити ваші програми значно швидшими.
---
Що таке асинхронне програмування? Уявіть, що ви готуєте сніданок. Синхронний підхід — це коли ви ставите чайник, чекаєте, поки він закипить, потім наливаєте чай, чекаєте, поки він завариться, і тільки потім робите тости. Виконується лише одна дія за раз. Асинхронний підхід дозволяє робити це ефективніше: ви ставите чайник і, *поки він кипить*, починаєте готувати тости. Коли чайник закипів, ви перемикаєтеся на нього, щоб залити чай, а потім повертаєтеся до тостів. Ви не простоюєте, а ефективно використовуєте час очікування. В програмуванні це означає, що програма може розпочати довготривалу операцію (наприклад, HTTP-запит) і, не чекаючи її завершення, переключитися на виконання інших завдань. Коли результат операції готовий, програма повертається до неї. Це ідеально підходить для I/O-bound (пов'язаних із введенням/виведенням) завдань.
Ключові концепції
asyncio
Щоб почати працювати з asyncio, потрібно зрозуміти кілька основних термінів.
#### async def: Корутини (Coroutines)
Корутина — це спеціальна функція, виконання якої можна призупинити та відновити. В Python вони оголошуються за допомогою синтаксису async def. Сама по собі корутина нічого не робить, доки її не запустять.
import asyncio
async def say_hello():
print("Привіт...")
await asyncio.sleep(1) # Призупиняємо виконання на 1 секунду
print("...світ!")
#### await: Очікування результату
Ключове слово await "каже" програмі: "Призупини виконання цієї корутини, доки операція праворуч не завершиться, а поки виконуй інші завдання". Використовувати await можна лише всередині async def функцій.
#### asyncio.run(): Запуск програми
Це головна точка входу для запуску асинхронної програми. Функція asyncio.run() створює цикл подій (event loop), запускає в ньому передану корутину і чекає на її завершення.
import asyncio
async def main():
print("Початок програми")
await say_hello()
print("Кінець програми")
# Запускаємо головну корутину
asyncio.run(main())
#### asyncio.create_task() та asyncio.gather(): Паралельне виконання
Щоб отримати справжню користь від асинхронності, потрібно запускати кілька завдань одночасно.
*
asyncio.create_task(coro) — планує виконання корутини coro в циклі подій. Вона не блокує виконання і повертає об'єкт Task.
*
asyncio.gather(*tasks) — дозволяє зібрати кілька завдань (або корутин) і запустити їх паралельно. Вона чекає, поки всі передані завдання завершаться, і повертає список їх результатів.
Практичний приклад: Асинхронний веб-скрейпер Давайте порівняємо швидкість синхронного та асинхронного підходів на прикладі завантаження заголовків кількох веб-сторінок.
Синхронна версія Для синхронних запитів використаємо популярну бібліотеку
requests.
# Потрібно встановити: pip install requests
import requests
import time
urls = [
"https://www.python.org/",
"https://docs.aiohttp.org/",
"https://github.com/",
"https://www.djangoproject.com/",
"https://flask.palletsprojects.com/"
]
def fetch_sync(url):
print(f"Fetching {url}...")
response = requests.get(url)
print(f"Finished {url}")
return response.status_code
start_time = time.time()
for url in urls:
fetch_sync(url)
end_time = time.time()
print(f"Синхронне виконання зайняло: {end_time - start_time:.2f} секунд.")
Кожен запит виконується послідовно. Якщо кожен запит триває близько 1 секунди, загальний час виконання буде приблизно 5 секунд.
Асинхронна версія з
aiohttp
Для асинхронних запитів нам знадобиться бібліотека aiohttp.
# Потрібно встановити: pip install aiohttp
import aiohttp
import asyncio
import time
urls = [
"https://www.python.org/",
"https://docs.aiohttp.org/",
"https://github.com/",
"https://www.djangoproject.com/",
"https://flask.palletsprojects.com/"
]
async def fetch_async(session, url):
print(f"Fetching {url}...")
async with session.get(url) as response:
print(f"Finished {url}")
return response.status
async def main():
async with aiohttp.ClientSession() as session:
tasks = [fetch_async(session, url) for url in urls]
await asyncio.gather(*tasks)
start_time = time.time()
asyncio.run(main())
end_time = time.time()
print(f"Асинхронне виконання зайняло: {end_time - start_time:.2f} секунд.")
У цьому випадку всі запити відправляються майже одночасно. Програма не чекає завершення одного запиту, щоб почати інший. В результаті загальний час виконання буде близьким до часу виконання найдовшого запиту, тобто приблизно 1 секунду. Різниця колосальна!
Висновок Асинхронне програмування з
asyncio — це потужний інструмент в арсеналі Python-розробника, який дозволяє створювати високопродуктивні та масштабовані застосунки. Хоча поріг входження може здатися трохи вищим, ніж у традиційному синхронному коді, переваги в швидкості для I/O-bound завдань є беззаперечними.
Почніть з простих корутин, експериментуйте з asyncio.gather і поступово інтегруйте асинхронність у свої проєкти. Ваші користувачі та ваші сервери будуть вам вдячні.
Якщо у вас виникли питання або є пропозиції щодо майбутніх тем, будь ласка, звертайтеся на **isholegg@gmail.com**.
---
**Ключові слова:** Python, asyncio, асинхронне програмування, корутини, await, async def, паралелізм, веб-скрейпінг, aiohttp, оптимізація коду, I/O-bound.
**Meta ** Покроковий гайд по асинхронному програмуванню в Python з бібліотекою asyncio. Дізнайтеся, як використовувати async/await для створення швидких I/O-застосунків. Практичні приклади коду включені.
Якщо у вас виникли питання, вбо ви бажаєте записатися на індивідуальний урок, замовити статтю (інструкцію) або придбати відеоурок, пишіть нам на: скайп: olegg.pann telegram, viber - +380937663911 додавайтесь у телеграм-канал: t.me/webyk email: oleggpann@gmail.com ми у fb: www.facebook.com/webprograming24 Обов`язково оперативно відповімо на усі запитіння
Поділіться в соцмережах
Подобные статьи:
