39269
Все самое полезное для питониста в одном канале. Список наших каналов: https://t.me/proglibrary/9197 Курс по ML: https://cl Для обратной связи: @proglibrary_feeedback_bot По рекламе: @proglib_adv РКН: https://gosuslugi.ru/snet/67b885cbd501cf3b2cdb5b36
📦 pixi: Универсальный менеджер пакетов для Python и C++
Если вы работаете в Data Science или AI, то наверняка сталкивались с «болью» системных зависимостей. Популярный сейчас uv невероятно быстр, но он бессилен, когда нужно установить не просто Python-библиотеку, а скомпилированные C++ пакеты (например, GDAL для геоданных или CUDA для GPU).
В чем проблема uv
Он управляет только пакетами из PyPI. Если вашему проекту нужны системные библиотеки, их приходится ставить вручную через apt-get или brew. Это рушит воспроизводимость: ваш коллега на другой ОС может потратить часы, пытаясь собрать окружение.
Почему стоит присмотреться к pixi
Это современная альтернатива conda, написанная на Rust, которая объединяет лучшее из миров uv и conda:
✅ Ставит и Python-пакеты (PyPI), и скомпилированные системные библиотеки (conda-forge) одной командой.
✅ Работает в 10–100 раз быстрее стандартной conda.
✅ В pixi.lock фиксируются абсолютно все зависимости, включая системные библиотеки, что гарантирует идентичность окружения на любом компьютере.
✅ Забудьте про сложные Makefile. Вы можете прописать команды запуска (train, test, preprocess) прямо в конфиге.
✅ Одна команда pixi install разворачивает проект на Windows, macOS и Linux без «танцев с бубном».
👇 Подробный разбор и примеры настройки — в статье.
📍 Навигация: Вакансии • Задачи • Собесы
Библиотека питониста
#буст
🐍 Простой Python Cheatsheet… но неожиданно мощный
Наткнулись на него и решили — точно стоит поделиться 👇
Он максимально:
• чистый
• структурированный
• без лишней воды
📍 Навигация: Вакансии • Задачи • Собесы
Библиотека питониста
#буст
📚Напоминаем про наш полный курс «Самоучитель по Python для начинающих»
Мы написали и собрали для вас в одну подборку все 25 глав и 230 практических заданий!
🐍 Часть 1: Особенности, сферы применения, установка, онлайн IDE
🐍 Часть 2: Все, что нужно для изучения Python с нуля – книги, сайты, каналы и курсы
🐍 Часть 3: Типы данных: преобразование и базовые операции
🐍 Часть 4: Методы работы со строками
🐍 Часть 5: Методы работы со списками и списковыми включениями
🐍 Часть 6: Методы работы со словарями и генераторами словарей
🐍 Часть 7: Методы работы с кортежами
🐍 Часть 8: Методы работы со множествами
🐍 Часть 9: Особенности цикла for
🐍 Часть 10: Условный цикл while
🐍 Часть 11: Функции с позиционными и именованными аргументами
🐍 Часть 12: Анонимные функции
🐍 Часть 13: Рекурсивные функции
🐍 Часть 14: Функции высшего порядка, замыкания и декораторы
🐍 Часть 15: Методы работы с файлами и файловой системой
🐍 Часть 16: Регулярные выражения
🐍 Часть 17: Основы скрапинга и парсинга
🐍 Часть 18: Основы ООП – инкапсуляция и наследование
🐍 Часть 19: Основы ООП – абстракция и полиморфизм
🐍 Часть 20: Графический интерфейс на Tkinter
🐍 Часть 21: Основы разработки игр на Pygame
🐍 Часть 22: Основы работы с SQLite
🐍 Часть 23: Основы веб-разработки на Flask
🐍 Часть 24: Основы работы с NumPy
🐍 Часть 25: Основы анализа данных с Pandas
🚀 ironkernel: сила NumPy, производительность Rust и свобода от GIL
Если вам знакома ситуация, когда NumPy перестает справляться, а писать расширения на C++ или Rust вручную слишком долго, обратите внимание на ironkernel. Это библиотека, которая позволяет писать выражения на Python (DSL), а исполнять их параллельно на Rust через движок Rayon.
Проект объединяет два мира:
1. Python DSL: Вы пишете привычный код с использованием декораторов или выражений.
2. Rust Engine: Код компилируется в промежуточное представление (IR), после чего Python отпускает GIL, и Rust задействует все ядра процессора для вычислений.
Самый простой способ — использовать декоратор @kernel.elementwise. Он превращает обычную функцию в параллельный кернел:
import numpy as np
from ironkernel import kernel, rt
@kernel.elementwise
def saxpy(a, x, y):
return a * x + y
# Подготовка данных
bx = rt.asarray(np.arange(1_000_000, dtype=np.float64))
by = rt.asarray(np.ones(1_000_000, dtype=np.float64))
# Запуск в Rust-рантайме (GIL отпущен!)
task = rt.go(kernel.map(saxpy, a=2.0, x=bx, y=by))
result = task.result().numpy()
out_ch = chan(4)
# Результат вычисления сразу летит в канал
rt.go(kernel.map(double, x=src), out=out_ch)
buf = out_ch.recv() # Получаем данные асинхронно
🐍 25 лет «бага» в Python, который никто не исправил
1 апреля 2026 года исполнился ровно 9731 день с момента, как сообщество Python узнало о… странности в работе со строками.
Суть проста:
"42 monkeys" + "1 snake"
"42 monkeys1 snake"
"41 monkeys and 1 fat snake"
print("42 monkeys" + "1 snake")
"41 monkeys and 1 fat snake"
новая реальность 🤪
🐸 Библиотека питониста
#развлекалово
🛠 Проблема: «грязные» тестовые данные
Когда вы тестируете функции, работающие с многострочным текстом, JSON или сложными объектами, декоратор @pytest.mark.parametrize быстро превращается в «простыню» текста.
Основные боли:
- Нарушение отступов: Многострочные строки (`"""`) ломают структуру кода.
- Дублирование логики: В каждом тесте приходится вызывать textwrap.dedent или Path().read_text().
- Нечитаемые ID: По умолчанию pytest генерирует ID теста из самих данных. Если данных много, лог тестов превращается в хаос.
Вместо того чтобы передавать в parametrize сырой список кортежей, создайте функцию (например, `nb_case`), которая подготавливает данные.
1. Умная обработка данных
Ваш хелпер может сам решать, что перед ним: путь к файлу или текст.
def nb_case(text, short, long, id=None):
if "\n" in text:
# Это текст: убираем лишние отступы
text = textwrap.dedent(text.lstrip("\n"))
else:
# Это путь: читаем файл
id = id or text
text = Path(text).read_text()
# Возвращаем специальный объект pytest.param
return pytest.param(text, short, long, id=id)
pytest.parampytest.param.
🧱 Clojure vs Python & R: новый взгляд на манипуляцию данными
Если вы привыкли к Pandas или dplyr, переход на Clojure с библиотекой tablecloth может показаться прыжком в другую вселенную. Но именно здесь раскрывается истинная мощь функционального программирования.
⚖️ Главное отличие: иммутабельность
В Pandas выполнение df.rename() или добавление колонки часто мутирует (изменяет) исходный объект. В Clojure любой датасет неизменяем.
— Каждая операция возвращает новый объект.
— Вам больше не нужно держать в голове текущее состояние переменной — код становится предсказуемым и легким для тестирования.
Clojure использует «потоковый макрос» -> (threading macro), который работает как пайп |> в R или цепочки методов в Python.
Задача: Отфильтровать пингвинов тяжелее 3800г и оставить только длину клюва.
Pandas: ds[ds["mass"] > 3800]["bill_length"]
tablecloth:
(-> ds
(tc/select-rows #(> (% "mass" 0) 3800))
(tc/select-columns "bill_length"))
nil с числом.(> nil 3800) вызовет ошибку.(% "col" 0). Это заставляет аналитика осознанно обрабатывать пропуски, а не полагаться на «магию» библиотеки.
#{"year" "sex"} — это функция, которая проверяет наличие элемента.
(tc/select-columns ds (complement #{"year"})) — выберет всё, КРОМЕ колонки year. Чистая математическая логика в коде.
🐸 Библиотека питониста
#развлекалово
🚀 Python 3.15: JIT-компилятор официально «встал на рельсы»
Хорошие новости для всей экосистемы: волонтерская команда CPython совершила прорыв. Новый JIT-компилятор (Just-In-Time), который буксовал в версиях 3.13 и 3.14, в альфа-версии Python 3.15 наконец-то начал показывать реальный прирост скорости.
Цели по производительности достигнуты с опережением графика:
➕ +11–12% ускорения на macOS (AArch64).
➕ +5–6% ускорения на Linux (x86_64).
➕ В отдельных сценариях зафиксирован рост производительности более чем на 100%.
Core Developer выделил три ключевых архитектурных решения:
1. Вместо компиляции отдельных методов, JIT теперь «подсматривает» за реально исполняемыми путями кода. Благодаря системе Dual Dispatch, основной интерпретатор остается быстрым, а JIT включается только там, где это эффективно. Это увеличило покрытие кода оптимизациями на 50%.
2. В Python управление памятью (`refcounts`) очень ресурсозатратно. Раньше каждая такая операция в JIT сопровождалась проверкой (ветвлением). Команда убрала эти лишние проверки в машинном коде, что дало колоссальный накопительный эффект.
3. После потери спонсорского финансирования проект перешел в руки сообщества. Сложные части JIT разбили на мелкие блоки, что позволило обычным C-разработчикам вносить вклад без глубоких знаний в теории компиляторов.
🔗 Ссылка на новость
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека питониста
#буст
🔥 Python 3.15 JIT: главные цифры
После трудностей в версиях 3.13 и 3.14, где JIT иногда даже замедлял работу, команда достигла прорывных показателей:
* +11–12% ускорения на macOS (AArch64).
* +5–6% на Linux (x86_64).
* В отдельных сценариях прирост доходит до 100% (двукратное ускорение!).
---
### 🛠 За счет чего произошел прорыв?
Кен Джин выделяет три технических «счастливых ставки», которые сработали:
#### 1. Трассирующая запись (Trace Recording)
Вместо того чтобы пытаться компилировать всё подряд, JIT теперь использует «умный» фронтенд.
* Dual Dispatch: Кен реализовал систему с двумя таблицами диспетчеризации. Это позволило оставить основной интерпретатор максимально быстрым, добавив лишь одну инструкцию для трассировки.
* Результат: Покрытие кода JIT-ом выросло на 50%.
#### 2. Удаление подсчета ссылок (Reference Count Elimination)
В Python управление памятью завязано на подсчете ссылок (`refcounts`). Раньше каждая такая операция в JIT сопровождалась дорогостоящей проверкой (ветвлением).
* Команда убрала лишние ветвления в машинном коде.
* Поскольку эти проверки происходят почти в каждой инструкции, эффект «накопительного ускорения» оказался колоссальным.
#### 3. Сообщество и «Мега-задачи»
Когда проект потерял основного спонсора в 2025 году, разработка перешла в руки волонтеров. Секрет успеха оказался в декомпозиции: сложные задачи JIT разбили на простые блоки, которые смог реализовать обычный C-программист без опыта в компиляторах.
---
### 🏁 Что это значит для нас?
1. 3.15 будет быстрее «из коробки»: Мы получаем честный прирост производительности без изменения кода.
2. Свободные потоки (Free-threading): Команда уже работает над поддержкой JIT для Python без GIL (Global Interpreter Lock). Это цель на версии 3.15/3.16.
3. JIT go brrr: Если раньше JIT был экспериментальной игрушкой, то теперь это серьезная технология, которая начинает оправдывать ожидания.
Как вы думаете, станет ли JIT в Python 3.15 поводом отказаться от специализированных решений вроде PyPy или Mojo для ваших задач? 👇
🔥 TorchCode — LeetCode для PyTorch
TorchCode — интерактивная среда (в Jupyter), где ты решаешь задачи по PyTorch, как на алгоритмических платформах.
40+ задач — от базовых до продвинутых
🔗 Ссылка на платформу
Библиотека дата-сайентиста
#буст
📚Напоминаем про наш полный курс «Самоучитель по Python для начинающих»
Мы написали и собрали для вас в одну подборку все 25 глав и 230 практических заданий!
🐍 Часть 1: Особенности, сферы применения, установка, онлайн IDE
🐍 Часть 2: Все, что нужно для изучения Python с нуля – книги, сайты, каналы и курсы
🐍 Часть 3: Типы данных: преобразование и базовые операции
🐍 Часть 4: Методы работы со строками
🐍 Часть 5: Методы работы со списками и списковыми включениями
🐍 Часть 6: Методы работы со словарями и генераторами словарей
🐍 Часть 7: Методы работы с кортежами
🐍 Часть 8: Методы работы со множествами
🐍 Часть 9: Особенности цикла for
🐍 Часть 10: Условный цикл while
🐍 Часть 11: Функции с позиционными и именованными аргументами
🐍 Часть 12: Анонимные функции
🐍 Часть 13: Рекурсивные функции
🐍 Часть 14: Функции высшего порядка, замыкания и декораторы
🐍 Часть 15: Методы работы с файлами и файловой системой
🐍 Часть 16: Регулярные выражения
🐍 Часть 17: Основы скрапинга и парсинга
🐍 Часть 18: Основы ООП – инкапсуляция и наследование
🐍 Часть 19: Основы ООП – абстракция и полиморфизм
🐍 Часть 20: Графический интерфейс на Tkinter
🐍 Часть 21: Основы разработки игр на Pygame
🐍 Часть 22: Основы работы с SQLite
🐍 Часть 23: Основы веб-разработки на Flask
🐍 Часть 24: Основы работы с NumPy
🐍 Часть 25: Основы анализа данных с Pandas
Почитали тут свежий отчёт по рынку ИИ-ускорителей в РФ: оказывается, 54% компаний тормозят внедрение ИИ исключительно из-за конских цен на инфраструктуру.
Ну, то есть написать пет-проект с вызовом API это задача на вечер, а вот запустить агента в продакшн так, чтобы он не сжёг бюджет отдела за неделю — суровая инженерия.
По сути, сейчас мало уметь собирать RAG. Нужно считать токены, настраивать time-travel дебаг в LangGraph и уметь роутить запросы на лету. Всё это мы учли в обновлённом курсе по разработке AI-агентов, где акцент сделан именно на AgentOps и жёсткий контроль ресурсов.
Также в программе:
— оценка качества, трейсинг и защита от деградации пайплайнов;
— мультиагентные паттерны и интеграция по протоколу MCP;
— локальный деплой Open Source под 152-ФЗ (когда данные нельзя выносить наружу).
Кажется, это единственный адекватный roadmap по переходу от блокнотов к enterprise-решениям.
Прямо сейчас можно урвать курс с увесистой скидкой (49 000 ₽ 62 990 ₽ за базовый тариф и 99 000 ₽ 124 990 ₽ за продвинутый трек), но стоит поторопиться — на потоке осталось всего 5 мест.
👉 Зафиксировать цену и начать собирать агентов, за которых не стыдно в проде
🏛 Когда пора создавать класс в Python
1. Требование фреймворка
Самый частый случай: вы используете библиотеку (Django, SQLAlchemy, Pydantic), где класс — это интерфейс. Например, в Django класс Model — это способ описать таблицу в базе данных. Здесь у вас просто нет выбора.
2. Вы постоянно передаете одни и те же данные в функции
Если у вас есть 5 функций, и каждая из них первым аргументом принимает один и тот же объект (например, server_connection или `user_session`), — это явный сигнал.
Вместо того чтобы «таскать» объект за собой, сделайте его атрибутом класса (`self.connection`), а функции превратите в методы. Код станет чище, а вызовы — короче: connection.send() вместо send_data(connection, data).
3. Улучшение читаемости и структуры данных
Иногда класс нужен просто для того, чтобы дать данным имя.
Плохо: Функция возвращает кортеж (103, 29). Что это? Ширина и высота? Или координаты X и Y?
Хорошо: Функция возвращает объект TerminalSize(columns=103, lines=29). Теперь любой, кто читает ваш код, сразу понимает, что происходит.
👉 Полная статья с полезностями
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека питониста
#буст
Python 3.3, вышедшая в сентябре 2012 года, часто незаслуженно забывается на фоне громких релизов вроде 3.5 (async/await) или 3.10 (pattern matching). Однако именно эта версия заложила фундамент, на котором стоит современная разработка.
Вот три ключевые инновации, которые навсегда изменили экосистему Python.
1. yield from: фундамент асинхронности
До Python 3.3 объединение генераторов требовало написания громоздких циклов for. Инструкция yield from позволила одному генератору полностью делегировать работу другому.
🔛 Вместо ручного перебора значений, вы просто «пробрасываете» управление.
🔛 yield from автоматически обрабатывает передачу значений через .send() и проброс исключений внутрь цепочки.
🔛 Без этой механики появление async/await в будущем было бы невозможно. Ключевое слово await — это, по сути, синтаксический сахар над yield from.
2. venv: стандартизация окружений
До 3.3 разработчики зависели от стороннего инструмента virtualenv. Релиз 3.3 ввел модуль venv прямо в стандартную библиотеку.
🔛 Теперь создание изолированного окружения для каждого проекта стало встроенной функцией языка (`python -m venv env`).
🔛 Это убило проблему «на моей машине работает», сделав использование requirements.txt в связке с виртуальным окружением золотым стандартом индустрии.
3. Namespace Packages: пакеты без границ
Раньше каждая папка в Python должна была содержать файл __init__.py, чтобы считаться пакетом. Python 3.3 ввел неявные пространства имен (Implicit Namespace Packages).
🔛 Теперь один логический пакет (например, `company.tools`) может быть физически разбит на несколько разных репозиториев или директорий.
🔛 Это упростило жизнь разработчикам плагинов и больших распределенных библиотек, избавив их от конфликтов при совпадении имен корневых папок.
🔗 Ссылка на полную статью
📍 Навигация: Вакансии • Задачи • Собесы
Библиотека питониста
#буст
🐍 Как сделать свой объект итерируемым в Python через `__getitem__`
В Python итерируемый объект — это любой объект, по которому можно пройтись в цикле for. Обычно это списки, строки, словари… но вы можете создать свой собственный!
👇 Секрет — метод `__getitem__`
Если ваш класс поддерживает доступ по индексам (`obj[0]`, obj[1] и т.д.), Python автоматически сможет итерироваться по нему.
Пример: арифметическая последовательность
class ArithmeticSequence:
def __init__(self, start: int, step: int, total: int) -> None:
self.start = start
self.step = step
self.total = total
def __getitem__(self, index: int) -> int:
if not 0 <= index < self.total:
raise IndexError(f"Invalid index {index}.")
return self.start + index * self.step
seq = ArithmeticSequence(5, 3, 6)
print(seq[3]) # 14
for value in seq:
print(value, end=", ")
# 5, 8, 11, 14, 17, 20,
class DictWrapper:
def __init__(self, values):
self.values = values
def __getitem__(self, index):
return self.values[index]
🧱 Cложность AsyncIO
Мы нашли интересную статью, в которой автор выделяет несколько фундаментальных проблем стандартной библиотеки Python:
– Огромное количество абстракций (Handle, Future, Task, Protocol, Transport). Мало кто может внятно объяснить разницу между ними.
– Дизайн asyncio завязан на идее «одного главного потока», что выглядит анахронизмом в эпоху Python без глобальной блокировки интерпретатора.
– Почему для работы с сокетом нужно вызывать методы цикла событий? Дизайн кажется перегруженным.
Вместо нагромождения объектов, TonIO сводит всё к двум сущностям: Event (Событие) и Waiter (Ожидающий).
1. Event: Простая обертка над атомарным флагом.
2. Waiter: Связующее звено между точкой приостановки (корутиной) и событием, которого она ждет.
Когда корутина доходит до await, она порождает Waiter, который регистрируется в цикле. Как только событие происходит (флаг меняется), Waiter «просыпается» и ставит корутину обратно в очередь на исполнение. Никаких «фьючерсов» в классическом понимании.
TonIO спроектирован в стиле Rust-библиотеки Tokio:
🔛 С помощью одного декоратора @tonio.main ваш код запускается на всех доступных ядрах процессора.
🔛 Главный поток Python (Main Thread) занимается исключительно низкоуровневым вводом-выводом (I/O). Весь прикладной код пользователя выполняется в отдельном пуле потоков. Вы больше не привязаны к «особому» главному потоку.
Готовы ли вы отказаться от совместимости со старыми библиотеками ради кратного роста производительности на современных многоядерных процессорах? 👇
📍 Навигация: Вакансии • Задачи • Собесы
Библиотека питониста
#буст
✌🏻 У нас две новости — хорошая и плохая!
Хорошая: Ваших знаний, скорее всего, хватит, чтобы собрать рабочую демку AI-агента в Colab. 🫡
Плохая: Вы вряд ли выведете его в прод, не обанкротившись на токенах и не слив базу. 🤯
Для защиты от таких сценариев мы полностью пересобрали курс «Разработка AI-агентов». Теперь внутри плотная работа с экономикой ресурсов, дебаг через time-travel в LangGraph, извлечение данных из кривых сканов для RAG и комплаенс по 152-ФЗ.
Если всё ещё сомневаетесь, послушайте голосовое от спикера курса Влада Прошинского, где он объясняет, как правильно тестировать агентов перед релизом.
⚡️ Срочно: Python Steering Council официально утвердил PEP 804 — «Strict Logic Mode»
В ветку Python 3.15.0a8 (релиз ожидается на следующей неделе) внезапно добавили механизм Boolean Enforcement, который вызвал бурю обсуждений в почтовой рассылке core-разработчиков.
Что меняется:
Интерпретатор теперь будет выдавать RuntimeWarning, если вы используете «неявное» приведение к bool в условиях.
Пример «устаревшего» кода:
items = []
if not items: # Теперь это вызовет Warning: "Implicit empty list evaluation"
print("Empty")
if len(items) == 0: # Официально одобренный синтаксис
print("Empty")
__bool__ у объектов в каждом if.Pydantic просто скинул в чат эмодзи с горящим домом.
🤝 3 признака дружелюбного класса
Чтобы класс не вызывал раздражения при использовании, он должен обладать тремя качествами:
1️⃣ Понятные аргументы: конструктор (`__init__`) принимает только то, что действительно нужно для создания объекта.
2️⃣ Красивое строковое представление: реализация метода __repr__. Вместо <Point object at 0x...> вы должны видеть Point(x=1, y=2, z=3). Это критично для логирования и отладки.
3️⃣ Логичное сравнение: реализация __eq__. По умолчанию Python сравнивает объекты по адресу в памяти. В дружелюбном классе два объекта с одинаковыми данными должны быть равны (`p1 == p2`).
⚡️ Dataclasses: дружелюбность «из коробки»
В современных версиях Python (3.7+) лучший способ создать дружелюбный класс — использовать декоратор @dataclass. Он автоматически генерирует методы __init__, __repr__ и __eq__ за вас.
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
z: float
__eq__ для объектов, у которых нет состояния (например, соединение с БД или логгер). Там важна идентичность объекта, а не равенство данных.enumerate`), стандартный `__repr__ вполне уместен.__iter__: позволит распаковывать объект как кортеж (`x, y, z = point`).__add__ / __sub__: если вы хотите складывать или вычитать объекты (например, векторы).dataclasses как мерило. Если ваш обычный класс менее удобен, чем аналогичный @dataclass, значит, его пора «подружить» с пользователем.
загадки разработчиков 😁
🐸 Библиотека питониста
#развлекалово
😱 Если ваш продукт не умеет отдавать данные в формате, понятном AI-агенту, то вас просто не существует
Скрипт не будет кликать по красивым кнопкам в браузере, он уйдёт к конкуренту с нормальным API. Перестроить архитектуру под машинных клиентов — это уже не хайп, а необходимое условие сохранения конкурентоспособности.
Как адаптировать продукт и не исчезнуть из выдачи:
— интегрировать MCP и A2A-взаимодействие, чтобы агенты могли вас читать;
— научиться контролировать стоимость (лимиты, кэш, роутинг между моделями);
— настроить AgentOps: трейсинг, логирование и отлов регрессий.
Всё это ждёт вас на обновлённом курсе «Разработка AI-агентов». Мы специально сделали фокус на утилитарном инжиниринге и production-ready решениях.
Кстати, до 29 марта можно забрать курс с большой скидкой, и стоит поторопиться — мест на потоке всё меньше.
Зафиксировать цену и начать деплоить агентов без слива бюджета 👈
📂 stdout и stderr: Два потока одного экрана
В операционных системах (Linux, macOS, Windows) каждому запущенному процессу по умолчанию открываются два выходных потока:
1. Standard Output (stdout): Сюда идет основной результат работы программы.
2. Standard Error (stderr): Сюда идут ошибки, предупреждения и диагностические сообщения.
В модуле sys эти потоки представлены как файлоподобные объекты. Функция print — это просто удобная обертка над ними.
🔛 Обычный вывод: print("Hello") или sys.stdout.write("Hello\n")
🔛 Вывод ошибки: print("Error!", file=sys.stderr) или sys.stderr.write("Error!\n")
🛠 Зачем разделять потоки
Главная причина — перенаправление (redirection). Представьте, что ваш скрипт обрабатывает 1000 файлов и записывает результат в лог. Если произойдет ошибка на 500-м файле, и вы пишете всё в один поток, ошибка «потеряется» внутри огромного текстового файла.
Примеры команд в терминале:
🔛 python script.py > output.txt — в файл попадет только stdout. Ошибки (stderr) по-прежнему будут видны на экране.
🔛 python script.py 2> errors.txt — на экране будет результат, а все ошибки уйдут в отдельный файл.
🔛 python script.py > all.txt 2>&1 — классический способ «склеить» потоки и записать всё в один файл.
💡 Когда стоит использовать stderr
Трей правильно замечает: stderr — это не только для критических ошибок. Используйте его для:
1. Tracebacks: Python сам пишет сюда дампы ошибок при падении.
2. Warnings: Модуль warnings использует этот поток.
3. Progress Bars: Если вы рисуете индикатор загрузки (например, через `tqdm`), лучше выводить его в stderr, чтобы он не засорял основной вывод данных.
4. Interactive Prompts: Вспомогательный текст (вроде приветствия в REPL) часто идет в stderr.
🏁 Практический совет
Если вы пишете CLI-утилиту, которой будут пользоваться другие люди (или ваши же скрипты):
> Всегда отправляйте полезные данные (те, что можно передать по цепочке другому скрипту через `|`) в stdout, а любые пояснения, логи и ошибки — в stderr.
🔥 AI Engineering Toolkit: 100+ инструментов для тех, кто строит на LLM
Прошли те времена, когда для создания ИИ-сервиса достаточно было одного API-ключа OpenAI.
Сегодня «AI Engineer» — это наполовину разработчик, наполовину архитектор данных и на 100% мастер автоматизации.
🔗 Ссылка на Github
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека питониста
#буст
🐸 Библиотека питониста
#развлекалово
⚡️ 100 дней IoT: для питонистов
Этот репозиторий — пошаговый план трансформации из «программиста интерфейсов» в инженера встроенных систем.
Автор использует MicroPython, ESP32 и Raspberry Pi Pico, что делает порог входа минимальным для любого питониста.
🔗 Ссылка на Github
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека питониста
#буст
✂️ 3+ способа убрать лишние пробелы в Python
Представьте, что у вас есть строка:"Это очень странное предложение."
Наша цель: оставить строго по одному пробелу между словами.
1. Золотой стандарт: Регулярные выражения (`re`)
Самый читаемый и производительный метод. Мы ищем паттерн «два и более пробела» и меняем его на один:
import re
def clean_spaces(text):
return re.sub(r" {2,}", " ", text)
def clean_spaces(text):
return " ".join(filter(None, text.split(" ")))
re.functools.Placeholder. Это позволяет нам крутить цикл замены replace(" ", " "), пока строка не перестанет меняться:
from functools import partial, Placeholder as _P
def fixedpoint(f, x):
while x != (x := f(x)):
pass
return x
# Заменяем два пробела на один, пока они не кончатся
space_replacer = partial(str.replace, _P, " ", " ")
clean_text = fixedpoint(space_replacer, "Много пробелов")
Почитали тут свежий отчёт по рынку ИИ-ускорителей в РФ: оказывается, 54% компаний тормозят внедрение ИИ исключительно из-за конских цен на инфраструктуру.
Ну, то есть написать пет-проект с вызовом API это задача на вечер, а вот запустить агента в продакшн так, чтобы он не сжёг бюджет отдела за неделю — суровая инженерия.
По сути, сейчас мало уметь собирать RAG. Нужно считать токены, настраивать time-travel дебаг в LangGraph и уметь роутить запросы на лету. Всё это мы учли в обновлённом курсе по разработке AI-агентов, где акцент сделан именно на AgentOps и жёсткий контроль ресурсов.
Также в программе:
— оценка качества, трейсинг и защита от деградации пайплайнов;
— мультиагентные паттерны и интеграция по протоколу MCP;
— локальный деплой Open Source под 152-ФЗ (когда данные нельзя выносить наружу).
Кажется, это единственный адекватный roadmap по переходу от блокнотов к enterprise-решениям.
Прямо сейчас можно урвать курс с увесистой скидкой (49 000 ₽ 62 990 ₽ за базовый тариф и 99 000 ₽ 124 990 ₽ за продвинутый трек), но стоит поторопиться — на потоке осталось всего 5 мест.
👉 Зафиксировать цену и начать собирать агентов, за которых не стыдно в проде
⚙️ Конфигурация в Python
Многие начинают с Option 1, потому что это быстро. Но по мере роста проекта поиск того, «откуда взялся этот API_KEY», превращается в детектив.
Почему Option 2 (Централизация) — это стандарт
Fail-Fast: Ваше приложение упадет при запуске, если забыт важный токен, а не через два часа работы, когда дело дойдет до вызова глубоко запрятанной функции.
Типизация: os.environ всегда возвращает строки. Если вам нужен RETRY_COUNT как int или DEBUG как bool, централизованный конфиг сделает приведение типов за вас.
Единый источник истины: Все настройки проекта видны в одном файле.
В 2026 году лучшим способом реализации Option 2 является библиотека pydantic-settings.
Она делает валидацию конфигурации автоматической:
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
db_url: str
api_key: str
debug: bool = False # Значение по умолчанию
# Автоматически читает из .env файла
model_config = SettingsConfigDict(env_file=".env")
settings = Settings()