TGStat
TGStat
Type to search
Advanced channel search
  • flag English
    Site language
    flag Russian flag English flag Uzbek
  • Sign In
  • Catalog
    Channels and groups catalog Regional compilations Thematic compilations Платные каналы Search for channels
    Add a channel/group
  • Ratings
    Rating of channels Rating of groups Posts rating
    Ratings of brands and people
  • Analytics
  • Search by posts
  • Telegram monitoring
  • Promotion
    Advertising through Yandex Business Advertising in channels through TGStat Agency Advertising on TGStat.ru website
Советы разработчикам (python и не только)

7 Aug 2025, 17:01

Open in Telegram Share Report

Asyncio и цикл событий

Чтобы понять, как рабоатет asyncio, давайте рассмотрим, как в Python работают функции.

Мы можем вызвать функцию, она выполнится. Просто интерпретатор берет её код и выполняет целиком. Если же мы берём функцию-генератор и просто вызываем, ничего не будет происходить. Тебе надо по ней пробежаться циклом или самому вызывая next. Когда мы вызываем next, код функции доходит до следующего yield и останавливается.

Представим, что у нас есть основной части программы цикл, который крутит этот генератор.

def foo():
yield 1
yield 2

for _ in foo():
pass

Если между yield вызывается обычная функция, то она выполняется как обычно, и не важно, что это происходит внутри генератора. А что, если наш генератор внутри себя вызывает другой генератор через yield from?

def foo():
yield 1
yield 2

def bar():
yield from foo()

for _ in bar():
pass

В этом случае, наш основной цикл просто крутится дальше как раньше, но уже выполняется не код первой функции, а переходит к той, что она вызвала и останавливается уже на её yield. То есть мы как бы крутим уже вложенный генератор, а не оригинальный. Нашему циклу не важно, откуда берутся шаги внутри функции: то ли она сама их выдумала, то ли получила из вложенных вызовов.

Проводя аналогию с asyncio наш главный цикл - это event loop, а генераторы - корутины. Корутины могут друг друга вызвать и циклу норм, он продолжает их крутить. Разница чисто синтаксическая: в asyncio используется await вместо yield.

Для полнцоенного использования тут не хватает одной важной детали.

На текущий момент у нас есть цикл, который постоянно дёргает генератор и при завершении шага переходит сразу к следующему. В реальности же мы хотим приостанавливать выполнение до получения данных из сети, наступления определенного времени и т.п. В норме мы хотим отдать управление циклу событий, чтобы он там что-то ещё мог поделать своё пока мы ждем. Но, как только слип завершится или сокет будет готов, надо вернуться назад и продолжить выполнение.

Итого, мы крутим цикл. Там генераторы, вызывающие генераторы. Мы это все крутим, крутим. Получаем оттуда объект, который наш loop умеет ожидать (Future). И каждый раз, прежде чем крутить дальше, ждём что он будет готов.

А раз нас есть цикл, который умеет ждать между вызовами next, он может в это время дёрнуть другой генератор, если у него есть их список. То есть, такие независимые генераторы - это таски asyncio.

Кратко:
1. Когда ты эвейтишь специальный объект, ты делаешь yield и отдаешь управление циклу событий
2. Когда ты эвейтишь другую корутину, ты просто проваливаешся внутрь
3. Когда цикл событий получает управление, он может заняться другими делами
4. У цикла событий дел два: дергать разные таски и ждать если все просили подождать внешнего мира

Дополнительные материалы:
• https://peps.python.org/pep-3156
• https://peps.python.org/pep-0380
• https://t.me/opensource_findings/869
• https://www.gevent.org/intro.html

5k 3 120 118 135
Catalog
Channels and groups catalog Channels compilations Search for channels Add a channel/group
Ratings
Rating of Telegram channels Rating of Telegram groups Posts rating Ratings of brands and people
API
API statistics Search API of posts API Callback
Our channels
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Read
Академия TGStat Telegram Research 2019 Telegram Research 2021 Telegram Research 2023
Contacts
Справочный центр Support Email Jobs
Miscellaneous
Terms and conditions Privacy policy Public offer
Our bots
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot