Асинхронные вызовы методов в Python: декораторы и коллбеки

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для реализации асинхронных операций в Python используйте ключевые слова async и await в сочетании с модулем asyncio. Вот простой пример:

Python
Скопировать код
import asyncio

async def async_task():
    print('Асинхронный процесс запущен, вот в улье вспыхивает суматоха 🐝.')
    await asyncio.sleep(1)  # Эмуляция задержки, как приготовление кофе ☕︎. 
    print('Асинхронный процесс завершился ровно как капучино — идеально гладко.')

# Запускаем асинхронное задание:
async def main():
    await async_task()

# Приводим в действие механизм asyncio!
asyncio.run(main())

asyncio.run(main()) выполняет роль стартовой точки. Метод main вызывает функцию async_task, а ключевое слово await используется для вызова других async функций или инициализации операций, поддерживающих asyncio, что обеспечивает неблокирующее и параллельное выполнение кода.

Кинга Идем в IT: пошаговый план для смены профессии

Async: погружение в детали

Помимо async/await есть и другие способы реализации асинхронности – threading и multiprocessing. Они обеспечивают другие возможности для асинхронных вызовов и могут быть представлены как супергерои со своими уникальными суперспособностями.

Threading — Флэш⚡ для I/O-интенсивных задач

Подобно Флэшу, мгновенно передвигающемуся из точки А в точку Б, threading в Python подходит для быстрых I/O-интенсивных операций, позволяя программе выполнять другие задачи во время ожидания IO-операций. Пример использования:

Python
Скопировать код
import threading

def async_thread_target():
    print("Тут расп unfolds IO-интенсивная реальность. Как чтение захватывающего детектива...")

thr = threading.Thread(target=async_thread_target)
thr.start()  # Пусть дело пойдёт своим чередом!
thr.join()   # Ожидаем окончания. Ведь мы не хотим остаться в неведении о развязке!

thr.start() запускает поток, а thr.join() ожидает его завершения. Проверить активность потока можно с помощью thr.is_alive().

Multiprocessing — Халк💪 для CPU-ограниченных задач

Когда речь идет о задачах, ограниченных процессорным временем, на помощь приходит multiprocessing. Он вскрывает пространство задач быстрее, чем можно произнести "РАЗРУШЕНИЕ!". Для распределения асинхронных вызовов методов подходит multiprocessing.Pool.apply_async:

Python
Скопировать код
from multiprocessing import Pool

def async_process_target(arg):
    print(f"Процесс номер {arg} выдаёт отчет, словно служащий регулярно отчитывается перед начальником.")
    return arg * arg

if __name__ == '__main__':
    pool = Pool()
    result = pool.apply_async(async_process_target, (2,))
    print(result.get())  # Готово – получено!

Выбор суперспособности

Не уверены, что выбрать из asyncio, threading и multiprocessing? Давайте вместе определим, где что будет более эффективным. Это как подбор подходящей суперособенности.

Когда предпочтительнее использовать asyncio

  • Для IO-интенсивных и интернет-ориентированных задач высокого уровня.
  • Когда нужно поддерживать множество одновременных соединений, как если бы вы были оператором телефонной станции.

Когда стоит выбрать threading

  • Если задачи обычно связаны с ожиданием: чтение с диска и запись на диск.
  • Потоки обеспечивают доступ к общей памяти, но стоит учесть Global Interpreter Lock (GIL).

Когда подойдет multiprocessing

  • Если вы решаете задачи, ограниченные процессорным временем.
  • Этот метод раскрывает все преимущества параллелизма на многопроцессорных системах.

Превосходство Twisted

Библиотека Twisted, хоть и не является встроенной в ядро Python, является настоящим авторитетом в мире асинхронного программирования. Twisted использует объекты Deferred для организации обратных вызовов, как при игре с кошкой и лазерной указкой:

Python
Скопировать код
from twisted.internet.defer import Deferred

def callback(result):
    print(f"Получен обратный вызов: {result}, как внезапная доставка пиццы 🍕")

deferred = Deferred()
deferred.addCallback(callback)
deferred.callback("Эхо от Twisted!")

С помощью Twisted вы можете организовать множество обратных вызовов и обработчиков ошибок. Также эта библиотека эффективно управляет сетевыми приложениями, требующими неблокирующего обмена данными.

Циклы событий и таймеры Asyncio

Asyncio предлагает циклы событий и таймеры, позволяющие получить больше контроля над асинхронными операциями:

Python
Скопировать код
async def periodic():
    while True:
        print('Периодическая задача работает, как стрелки древних часов, точно измеряют время.')
        await asyncio.sleep(2)  # Регулярные паузы длиной 2 секунды

loop = asyncio.get_event_loop()
loop.run_until_complete(periodic())

Здесь loop.run_until_complete() выполняет задания до их завершения, а asyncio.sleep() заводит паузы с определенным интервалом.

Визуализация

Чтобы лучше понять асинхронные вызовы в Python, представьте очередь в столовую:

Markdown
Скопировать код
  🍽️ [Синхронно]: Берут тарелку, начинают есть, и только после этого следующий человек подходит.
  
  🍽️ 🚀 [Асинхронно]: Берут тарелку и **телепортируются** к столу, начинают есть. Но в этот момент следующий посетитель уже берет свою порцию.

async методы позволяют не ожидать завершения одного действия перед началом следующего. Он может начаться в тот момент, когда предыдущее ещё выполняется!

Python
Скопировать код
import asyncio

async def async_method():
    await some_io_task()  # 🚀 Телепорт на место выполнения ...
    # А следующий посетитель уже подходит к очереди!

Так async методы функционируют как хорошо отлаженная линия в столовой — быстро и эффективно.

Полезные материалы

  1. asyncio — Asynchronous I/O — Документация Python 3.12.2 — официальная документация модуля asyncio Python.
  2. Python Asynchronous Programming – AsyncIO & Async/Await – YouTube — видеоурок по асинхронному программированию на Python с помощью AsyncIO.
  3. asyncio — Asynchronous I/O, event loop, and concurrency tools — PyMOTW 3 — детальное руководство по асинхронному вводу-выводу, циклам событий и инструментам параллелизма в Python.
  4. Medium — обзор последовательной и конкурентной обработки с использованием async/await в Python.
  5. Medium — анализ asyncio в контексте Python и Node.js для создания масштабируемых микросервисов.