Привет! С вами Иван, и сегодня у нас на повестке — асинхронные итераторы и асинхронные контекстные менеджеры в Python. Эти инструменты — не только про «магические» async и await, они воплощают суть современной асинхронности: элегантный контроль над ресурсами и процессами в неблокирующем стиле. Давайте разберёмся по полочкам!
### Асинхронные итераторы
Асинхронный итератор — это объект, который поддерживает метод
Вот пример простейшего своего асинхронного итератора:
Асинхронные итераторы блестяще подходят, если вы хотите, чтобы программа не простаивала в ожидании внешних данных, а занималась другими делами.
### Асинхронные контекстные менеджеры
А теперь представьте ситуацию: для работы с внешним ресурсом (например, подключение к БД или файлу) вам нужен асинхронный код. Здесь появляются асинхронные контекстные менеджеры (
Пример на основе таймера:
Такой подход поможет безопасно выделять и освобождать ресурсы даже в асинхронных задачах. Асинхронные менеджеры активно используют библиотеки aiohttp, aiomysql и другие современные async-инструменты.
### Итог
Асинхронные итераторы и асинхронные контекстные менеджеры — это две стороны одной монеты: грамотное и безопасное управление асинхронными процессами. Освоив их, вы сможете писать «живые» и эффективные приложения, не жертвуя структурой и чистотой кода.
В следующий раз разберём, где на практике искать и как использовать готовые асинхронные инструменты в популярных библиотеках!
### Асинхронные итераторы
Асинхронный итератор — это объект, который поддерживает метод
__anext__
и интерфейс __aiter__
, а работать с ним можно через async for
. Обычно они нужны, если вы хотите итерироваться по данным, загружаемым с задержками: например, получать ответы от API по мере их поступления.Вот пример простейшего своего асинхронного итератора:
class AsyncCounter:
def __init__(self, start, end):
self.current = start
self.end = end
def __aiter__(self):
return self
async def __anext__(self):
if self.current >= self.end:
raise StopAsyncIteration
await asyncio.sleep(0.5) # имитация задержки
self.current += 1
return self.current - 1
import asyncio
async def main():
async for number in AsyncCounter(0, 3):
print(number)
asyncio.run(main())
Асинхронные итераторы блестяще подходят, если вы хотите, чтобы программа не простаивала в ожидании внешних данных, а занималась другими делами.
### Асинхронные контекстные менеджеры
А теперь представьте ситуацию: для работы с внешним ресурсом (например, подключение к БД или файлу) вам нужен асинхронный код. Здесь появляются асинхронные контекстные менеджеры (
async with
), которые реализуют методы __aenter__
и __aexit__
.Пример на основе таймера:
class AsyncTimer:
async def __aenter__(self):
self.start = asyncio.get_event_loop().time()
return self
async def __aexit__(self, exc_type, exc, tb):
end = asyncio.get_event_loop().time()
print(f'Duration: {end - self.start:.2f} seconds')
import asyncio
async def do_work():
await asyncio.sleep(1)
async def main():
async with AsyncTimer():
await do_work()
asyncio.run(main())
Такой подход поможет безопасно выделять и освобождать ресурсы даже в асинхронных задачах. Асинхронные менеджеры активно используют библиотеки aiohttp, aiomysql и другие современные async-инструменты.
### Итог
Асинхронные итераторы и асинхронные контекстные менеджеры — это две стороны одной монеты: грамотное и безопасное управление асинхронными процессами. Освоив их, вы сможете писать «живые» и эффективные приложения, не жертвуя структурой и чистотой кода.
В следующий раз разберём, где на практике искать и как использовать готовые асинхронные инструменты в популярных библиотеках!
👍1
Привет! На связи Иван, и сегодня поговорим о том, как заставить ваш ноутбук работать за троих (или даже десятерых) с помощью Python! Тема выпуска — библиотека joblib и ее простые способы организовать параллельные вычисления.
Постой, зачем мне параллельные вычисления?
Очень просто: если у вас есть повторяющиеся задачи, которые не зависят друг от друга, — например, обработка большого списка изображений или вычисления для разных наборов данных — их можно запускать одновременно. Это ускорит работу почти в разы, особенно на многоядерных процессорах.
Почему joblib, а не стандартный multiprocessing?
joblib проще! Фактически, она создана для тех случаев, когда нужно параллелить обработку данных, начиная от простых циклов до длительных вычислений в Data Science и ML.
Минимальный пример:
Допустим, у нас есть функция, вычисляющая сумму квадратов для заданного числа, и список чисел.
-
-
Фишка с joblib:
joblib сам заботится о создании процессов. Просто говорите, сколько “работников” (
Параллельная обработка файлов:
Когда joblib особенно полезна?
- При работе с большими наборами данных.
- Для ускорения преобразований в циклах.
- Для сложных аналитических вычислений.
joblib также отлично “дружит” с библиотеками для машинного обучения, например, scikit-learn, в котором многие функции используют joblib внутри!
Попробуйте joblib, если хочется ускорить рутинные задачи и “разогнать” свои вычисления за пару строк кода!
Постой, зачем мне параллельные вычисления?
Очень просто: если у вас есть повторяющиеся задачи, которые не зависят друг от друга, — например, обработка большого списка изображений или вычисления для разных наборов данных — их можно запускать одновременно. Это ускорит работу почти в разы, особенно на многоядерных процессорах.
Почему joblib, а не стандартный multiprocessing?
joblib проще! Фактически, она создана для тех случаев, когда нужно параллелить обработку данных, начиная от простых циклов до длительных вычислений в Data Science и ML.
Минимальный пример:
Допустим, у нас есть функция, вычисляющая сумму квадратов для заданного числа, и список чисел.
from joblib import Parallel, delayed
def calc_square_sum(n):
return sum(i * i for i in range(n))
numbers = [10**6, 2 * 10**6, 3 * 10**6, 4 * 10**6]
results = Parallel(n_jobs=2)(delayed(calc_square_sum)(n) for n in numbers)
print(results)
-
Parallel(n_jobs=2)
— запускаем два параллельных процесса.-
delayed(calc_square_sum)(n)
— “оборачиваем” функцию, чтобы она запускалась параллельно для каждого n
.Фишка с joblib:
joblib сам заботится о создании процессов. Просто говорите, сколько “работников” (
n_jobs
) хотите, и библиотека запустит задачи параллельно.Параллельная обработка файлов:
import os
from joblib import Parallel, delayed
def process_file(filename):
# Тут могут быть чтение, обработка, парсинг и т.п.
return os.path.getsize(filename)
file_list = ['file1.txt', 'file2.txt', 'file3.txt']
sizes = Parallel(n_jobs=3)(delayed(process_file)(fname) for fname in file_list)
print(sizes)
Когда joblib особенно полезна?
- При работе с большими наборами данных.
- Для ускорения преобразований в циклах.
- Для сложных аналитических вычислений.
joblib также отлично “дружит” с библиотеками для машинного обучения, например, scikit-learn, в котором многие функции используют joblib внутри!
Попробуйте joblib, если хочется ускорить рутинные задачи и “разогнать” свои вычисления за пару строк кода!
👍1