WEBYK WEBYK Індивідуальні OnLine уроки з web технологій
+38 093 766 39 11
oleggpann@gmail.com

Asyncio в Python: Практичний посібник з асинхронного програмування

### Ця стаття є детальним посібником з використання модуля asyncio в Python для написання ефективного асинхронного коду. Ми розглянемо ключові концепції, такі як корутини, цикл подій та завдання, а також продемонструємо переваги асинхронності на практичному прикладі веб-скрейпера.

У сучасному світі розробки програмного забезпечення швидкість та ефективність є критично важливими. Коли ваша програма виконує багато операцій, пов'язаних з очікуванням (наприклад, мережеві запити, читання файлів або запити до бази даних), традиційний синхронний підхід може стати "вузьким місцем". Кожен запит блокує виконання програми, доки не буде отримано відповідь. Асинхронне програмування вирішує цю проблему, дозволяючи програмі виконувати інші завдання під час очікування. Python надає потужний інструмент для цього — бібліотеку asyncio. Давайте розберемося, як вона працює і як її можна використовувати для значного прискорення ваших I/O-bound застосунків. ---

Що таке асинхронне програмування?

Уявіть собі шеф-кухаря на кухні.

* **Синхронний підхід:** Кухар береться за перше замовлення. Він ставить варитися суп і стоїть над каструлею, чекаючи, доки той закипить. Потім він починає нарізати овочі для салату і чекає, поки наріже всі. І лише після повного завершення одного завдання він переходить до іншого. Ефективно? Не дуже.

* **Асинхронний підхід:** Кухар ставить варитися суп. Поки суп закипає, він не чекає, а починає нарізати овочі для салату. Потім він ставить стейк на гриль. Він перемикається між завданнями, використовуючи час очікування для виконання іншої корисної роботи. Асинхронне програмування працює за тим же принципом. Замість того, щоб блокувати весь потік виконання під час очікування завершення операції вводу-виводу (I/O), програма передає керування іншим завданням. Це ідеально підходить для завдань, де процесор переважно простоює.

Ключові концепції asyncio

Щоб ефективно працювати з asyncio, потрібно зрозуміти кілька основних термінів.

Корутини (Coroutines) та async / await


**Корутина** (або співпрограма) — це основна одиниця виконання в asyncio. Це функція, виконання якої можна призупинити та відновити. В Python корутини створюються за допомогою ключового слова async def.
import asyncio

async def say_hello():
    print("Привіт...")
    await asyncio.sleep(1) # Призупиняємо виконання на 1 секунду
    print("...світ!")
Ключове слово await використовується для виклику іншої корутини. Воно каже циклу подій: "Я зараз буду чекати, тож ти можеш поки що виконати якусь іншу роботу".

Цикл подій (Event Loop)


**Цикл подій** — це "серце" будь-якої програми на asyncio. Він відповідає за керування та розподіл часу виконання між різними корутинами. Він запускає їх, призупиняє, коли вони очікують (на await), і відновлює, коли вони готові продовжити. Щоб запустити головну корутину, використовується функція asyncio.run():
import asyncio

async def main():
    print("Початок програми")
    await say_hello()
    print("Кінець програми")

# Запуск циклу подій для виконання корутини main()
asyncio.run(main())


Завдання (Tasks)

Щоб кілька корутин виконувались одночасно (конкурентно), їх потрібно "загорнути" в **завдання** (Task). Завдання — це об'єкт, який планує виконання корутини в циклі подій. Створити завдання можна за допомогою asyncio.create_task().
import asyncio

async def my_task(name, delay):
    print(f"Завдання {name} почалося")
    await asyncio.sleep(delay)
    print(f"Завдання {name} завершилося")

async def main():
    task1 = asyncio.create_task(my_task("A", 2))
    task2 = asyncio.create_task(my_task("B", 1))

    await task1
    await task2

asyncio.run(main())
У цьому прикладі task2 завершиться раніше, ніж task1, хоча було запущено пізніше.

Практичний приклад: Асинхронний веб-скрейпер

Найкращий спосіб зрозуміти силу asyncio — це порівняти його з синхронним кодом на реальному завданні, наприклад, завантаженні кількох веб-сторінок. Для цього нам знадобляться бібліотеки requests (для синхронного коду) та aiohttp (для асинхронного). pip install requests aiohttp

Синхронна версія

import requests
import time

urls = [
    'https://www.python.org/',
    'https://www.djangoproject.com/',
    'https://flask.palletsprojects.com/',
    'https://fastapi.tiangolo.com/',
    'https://docs.aiohttp.org/'
]

def fetch_sync(url):
    print(f"Завантажую {url}")
    _ = requests.get(url)
    print(f"Завантажено {url}")

start_time = time.time()
for url in urls:
    fetch_sync(url)
end_time = time.time()

print(f"Синхронне виконання зайняло: {end_time - start_time:.2f} секунд")
Кожна URL-адреса завантажується послідовно. Програма чекає, доки завершиться один запит, перш ніж почати наступний.

Асинхронна версія

import aiohttp
import asyncio
import time

urls = [
    'https://www.python.org/',
    'https://www.djangoproject.com/',
    'https://flask.palletsprojects.com/',
    'https://fastapi.tiangolo.com/',
    'https://docs.aiohttp.org/'
]

async def fetch_async(session, url):
    print(f"Завантажую {url}")
    async with session.get(url) as response:
        _ = await response.text()
        print(f"Завантажено {url}")

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} секунд")
Тут ми створюємо список завдань і запускаємо їх конкурентно за допомогою asyncio.gather(). Програма не чекає завершення одного запиту, а одразу надсилає всі. Результат — значне скорочення часу виконання.

Коли варто використовувати asyncio?

asyncio не є "срібною кулею" для всіх проблем. Його варто використовувати для **I/O-bound** завдань:

* Мережеві операції (HTTP-запити, робота з API).

* Робота з базами даних.

* Читання та запис файлів на диск.

* Створення веб-серверів, чат-ботів, стрімінгових сервісів. Для **CPU-bound** завдань (складні математичні обчислення, обробка зображень), де процесор постійно завантажений, краще підійде мультипроцесинг (multiprocessing), оскільки asyncio виконується в одному потоці і не дасть приросту продуктивності.

Висновок Асинхронне програмування з asyncio — це потужний підхід для створення швидких та масштабованих додатків у Python. Хоча поріг входження може здатися трохи вищим, ніж у традиційного синхронного коду, переваги в продуктивності для I/O-завдань є беззаперечними. Розуміння корутин, циклу подій та завдань відкриває двері до нового рівня ефективності ваших програм. Якщо у вас виникли питання або є пропозиції щодо майбутніх тем, не соромтеся писати на **isholegg@gmail.com**. ---
**Ключові слова:** asyncio, Python, асинхронне програмування, корутини, async/await, event loop, I/O-bound, веб-скрейпінг, aiohttp, конкурентність, продуктивність.
**Meta ** Дізнайтеся, як використовувати asyncio в Python для створення швидких та ефективних програм. Практичний посібник з асинхронного програмування з прикладами коду для I/O-bound завдань, включаючи веб-скрейпінг.

Якщо у вас виникли питання, вбо ви бажаєте записатися на індивідуальний урок, замовити статтю (інструкцію) або придбати відеоурок, пишіть нам на:
скайп: olegg.pann
telegram, viber - +380937663911
додавайтесь у телеграм-канал: t.me/webyk
email: oleggpann@gmail.com
ми у fb: www.facebook.com/webprograming24
Обов`язково оперативно відповімо на усі запитіння


Поділіться в соцмережах



Подобные статьи:


facebook
×
Підришіться на цікаві пости.
Підписатись