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

Асинхронне програмування в Python з asyncio: Від теорії до практики

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

У сучасному світі розробки програмного забезпечення швидкість та ефективність є ключовими факторами успіху. Коли ваша програма взаємодіє із зовнішніми ресурсами — робить запити до API, звертається до бази даних або читає файли з диска — вона часто витрачає час на очікування відповіді. Традиційний, синхронний підхід змушує всю програму "завмирати" в цей час. Асинхронне програмування пропонує елегантне вирішення цієї проблеми, дозволяючи виконувати інші завдання, поки одне очікує завершення. У Python головним інструментом для реалізації асинхронності є вбудована бібліотека asyncio. Вона надає потужний фреймворк для написання конкурентного коду з використанням синтаксису async/await. Давайте зануримось у цей світ і розберемося, як змусити ваш код працювати швидше та ефективніше. ---

Що таке асинхронність і навіщо вона потрібна? Щоб зрозуміти переваги асинхронного підходу, спершу порівняймо його із синхронним.

Синхронний vs. Асинхронний підхід


**Синхронний (блокуючий) код** виконується послідовно, рядок за рядком. Якщо програма зустрічає операцію, що вимагає очікування (наприклад, HTTP-запит), вона зупиняється і чекає, доки операція не завершиться.

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

* **Аналогія:** Ви ставите чайник і, поки він гріється, дістаєте чашку, насипаєте в неї каву та цукор. Коли чайник закипить, ви повертаєтеся до нього і заливаєте воду. Ви не простоювали, а ефективно використали час очікування. asyncio ідеально підходить для: - Веб-скрейпінгу (одночасного завантаження багатьох сторінок). - Роботи з API (відправлення сотень запитів без очікування кожного окремо). - Мережевих серверів та клієнтів. - Взаємодії з базами даних в асинхронному режимі.

Основи asyncio в Python Для роботи з asyncio потрібно засвоїти кілька ключових понять.

Ключові слова async та await

Це основа синтаксису асинхронного програмування в Python, введена в версії 3.5. - async def: Це ключове слово використовується для оголошення **корутини** (coroutine). Корутина — це спеціальна функція, виконання якої можна призупинити та відновити. - await: Це слово можна використовувати тільки всередині async def функції. Воно говорить програмі: "Призупини виконання цієї корутини тут, доки не отримаєш результат від виразу праворуч, а тим часом цикл подій може виконувати інші завдання".

Корутини (Coroutines)

Простий виклик корутини нічого не виконає. Він просто поверне об'єкт корутини.
import asyncio

async def my_coroutine():
    print("Привіт з корутини!")
    return 42

# Просто виклик функції не виконає її код
coro_obj = my_coroutine()
print(coro_obj)
# Виведе щось на кшталт: 
Щоб запустити корутину, її потрібно передати в цикл подій.

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

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

async def main():
    print("Початок виконання...")
    await asyncio.sleep(1) # Симулюємо I/O операцію
    print("...завершення.")

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


Практичний приклад: Асинхронний веб-скрейпер Давайте порівняємо швидкість синхронного та асинхронного підходів на прикладі завантаження заголовків кількох веб-сторінок. Для цього нам знадобляться бібліотеки requests (для синхронного коду) та aiohttp (для асинхронного). Встановіть їх: pip install requests aiohttp

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

Використовуємо стандартну бібліотеку requests.
import requests
import time

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

def fetch_sync(url):
    try:
        response = requests.get(url)
        print(f"Отримано заголовок для {url}: {response.text[:30].strip()}...")
    except Exception as e:
        print(f"Помилка для {url}: {e}")

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

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

Асинхронна версія з asyncio та aiohttp

Тепер перепишемо той самий код з використанням asyncio.
import asyncio
import aiohttp
import time

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

async def fetch_async(session, url):
    try:
        async with session.get(url) as response:
            text = await response.text()
            print(f"Отримано заголовок для {url}: {text[:30].strip()}...")
    except Exception as e:
        print(f"Помилка для {url}: {e}")

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"\nАсинхронне виконання зайняло: {end_time - start_time:.2f} секунд.")

**Що тут відбувається?** 1. fetch_async — це корутина, яка робить один асинхронний запит. 2. main — основна корутина, яка створює список завдань (tasks) для кожного URL. 3. asyncio.gather(*tasks) — це ключова функція. Вона збирає всі корутини і запускає їх "одночасно" (конкурентно). Цикл подій перемикається між ними, поки вони очікують відповіді від серверів. Запустивши обидва скрипти, ви побачите, що асинхронна версія виконується значно швидше. Загальний час її роботи буде близький до часу найдовшого запиту, а не до їх суми.

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

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


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



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


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