Розбираємося з `async` та `await`

2 хв. читання

Це частина циклу статей про синтаксичний цукор у Python, у якій ми розглянемо роботу async та await.

Розбираємося з async

Найперше гляньмо під капот async. Виявляється, що розібратися з async def досить просто завдяки декоратору types.coroutine, від якого і походить async def. Цей декоратор встановлює прапорець на об'єкті коду для генератора, щоб відрізнити його від будь-якого іншого простого генератора. Іншими словами, функції async і є генераторами.

Розбираємося з await

Очевидно, що вираз awaitє похідним відyield from, але з двома основними особливостями: перевіркою того, чи може об'єкт застосовуватися з функцією await, і підтримкою цих об'єктів, які визначає __await__().

Стандартна бібліотека надає функцію inspect.isawaitable(), щоб визначити, чи може об'єкт застосовуватися з функцією await. З першою особливістю розібралися.

Інша особливість — це те, як викликати співпрограму, або корутину, через yield from. Об'єкти, що працюють з функцією await, можуть або визначатися як __await __ (), який повертає ітероване, або бути генератором, позначеним як співпрограма. Відтак ми повинні підтримувати обидва ці сценарії. Як і у попередніх прикладах зі спеціальними методами, нам потрібно отримати метод __await__() безпосередньо з типу, а потім викликати його разом з об'єктом. Інакше обидва типи об'єктів, що можуть застосовуватися з функцією await, стають об'єктами, які можна передати до yield from.

def _await(coroutine):
    """Simulate `await coroutine`."""
    if not inspect.isawaitable(coroutine):
        msg = f"object {builtins.type(coroutine)} can't be used in 'await' expression"
        raise TypeError(msg)
    coroutine_type = builtins.type(coroutine)
    try:
        __await__ = _mro_getattr(coroutine_type, "__await__")
    except AttributeError:
        awaitable = coroutine
    else:
        awaitable = __await__(coroutine)
    yield from awaitable

Код для імітації await

Завдяки тому, як у Python побудовано async та await, ми вже мали всі потрібні блоки, щоб розібратися з синтаксисом і, по суті, перейти на попередні версії Python!

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.8K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація