Python для начинающих
1.06K subscribers
299 photos
3 videos
232 files
62 links
Python для начинающих
Download Telegram
Привет! С вами Иван, и сегодня у нас на повестке — асинхронные итераторы и асинхронные контекстные менеджеры в Python. Эти инструменты — не только про «магические» async и await, они воплощают суть современной асинхронности: элегантный контроль над ресурсами и процессами в неблокирующем стиле. Давайте разберёмся по полочкам!

### Асинхронные итераторы

Асинхронный итератор — это объект, который поддерживает метод __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
- Как использовать библиотеку joblib для параллельных вычислений
Привет! На связи Иван, и сегодня поговорим о том, как заставить ваш ноутбук работать за троих (или даже десятерых) с помощью Python! Тема выпуска — библиотека 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