
Кеширование в Python: от lru_cache до Redis без мифов
Один и тот же кеш ведёт себя по-разному в скрипте, в воркере Celery и под четырьмя процессами Gunicorn. Разбираем, где lru_cache спасает, где врёт, и когда пора выносить кеш в Redis.

Один и тот же кеш ведёт себя по-разному в скрипте, в воркере Celery и под четырьмя процессами Gunicorn. Разбираем, где lru_cache спасает, где врёт, и когда пора выносить кеш в Redis.

Скрипт съел 3 ГБ на обработке файла в 200 МБ, и htop это показал, но не сказал где. Разбираем, как найти строку-виновника через tracemalloc и line-by-line профилирование.

Скрипт обрабатывает 10 000 записей 40 секунд, а вы не знаете почему. Разбираем, как cProfile находит виноватую функцию, а line_profiler — виноватую строку внутри неё, и где эти инструменты врут.

Три инструмента управления зависимостями Python решают одну задачу по-разному: где-то важна скорость установки, где-то предсказуемый lock-файл, где-то совместимость со стандартами. Разбираем, чем платишь за каждый выбор.

Пошаговый гайд: как собрать проект с pyproject.toml, проверить сборку на TestPyPI и выложить пакет в PyPI так, чтобы его можно было поставить через pip install.

setup.py больше не нужен для сборки: PEP 517/518 сделали pyproject.toml единым файлом конфигурации. Разбираем, что туда писать и чем платишь за переход на build-бэкенды.

Плоский проект с одним файлом рано или поздно превращается в кашу из циклических импортов и запусков через python script.py из корня. Разбираем, как раскладывать пакеты, где держать точку входа и почему src-layout спасает от импортов-призраков.

В SQLAlchemy 2.0 исчез Query.get, изменился select(), а сессии стали строже к неявным запросам. Разбираем, какие вызовы придётся переписать и как перевести проект без переписывания с нуля.

Три способа ходить в PostgreSQL из Python дают разный контроль над SQL и разную цену за удобство. Разбираем, где каждый выигрывает и чем платит.

GIL не даёт потокам считать параллельно, а процессы дают — но с ценой на сериализацию и запуск. Разбираем, какой инструмент из multiprocessing брать под задачу и где он ломается.

Вы распараллелили расчёт на четыре потока, а он стал работать не быстрее, а иногда медленнее. Разбираем, как GIL в CPython решает, кто исполняет байт-код, и когда потоки реально помогают.

Скрипт с requests опрашивает 200 URL за 90 секунд, переписанный на aiohttp — за 4. А иногда наоборот: asyncio добавляет накладных расходов и не даёт ничего. Разбираем, где проходит граница.