Zen of Python
18.9K subscribers
1.39K photos
202 videos
38 files
3.56K links
Полный Дзен Пайтона в одном канале

Разместить рекламу: @tproger_sales_bot

Правила общения: https://tprg.ru/rules

Другие каналы: @tproger_channels

Сайт: https://tprg.ru/site

Регистрация в перечне РКН: https://tprg.ru/xZOL
Download Telegram
После обновления на Polars 2.0 ваши join и group_by могут вернуть строки в другом порядке

Ричи Винк выпустил первый release candidate Polars 2.0 и сам называет релиз скучным: новых функций почти нет, мажорную версию подняли, чтобы избавиться от старых решений и поменять дефолты.

Главная смена дефолта: все запросы LazyFrame теперь идут через потоковый движок, который обрабатывает данные порциями. В совокупности авторы ожидают «легко в 5 раз быстрее» и заметно меньше памяти. Плата за это в том, что порядок строк после операций больше не гарантирован.

Если код где-то молча полагался на порядок после join или group_by, он сломается тихо. К релизу выложен полный migration guide, и заглянуть в него стоит до того, как обновитесь.
Почему CPython остаётся стековой машиной, а её соседи уходят на регистры

Байткод CPython стековый: a + b это LOAD_FAST a, LOAD_FAST b, BINARY_OP. Максим Шевалье-Буавер, в прошлом автор YJIT для Ruby, измерила на своём языке Plush, сколько стоит такая модель: после перехода на регистровый байткод, где то же сложение одна инструкция с тремя операндами, медианное ускорение по тестам составило 2,07 раза, максимальное 3,37, а тесты сборщика мусора не изменились вовсе.

Замеры честные: 11 чередующихся запусков, медиана, повтор набора; в сравнении участвовал и CPython 3.14.6, но автор оговаривает разную семантику языков. Вывод один: в интерпретаторе главный рычаг это число инструкций на диспетчеризацию. Как устроено новое 64-битное слово инструкции и почему Lua ограничена 255 регистрами на фрейм, на сайте.

@zen_of_python
CPython официально поддерживает RISC-V как платформу третьего уровня

Работа шла несколько месяцев, и теперь RISC-V официально поддержан в CPython как tier 3. Для питониста это означает, что сборки под эту архитектуру перестали быть самодеятельностью и попали в зону ответственности проекта.

RISC-V это открытая система команд: в отличие от x86 и ARM, она развивается как открытый стандарт, и реализовать её может кто угодно. Экосистема за последние годы выросла заметно.

Третий уровень означает поддержку без гарантий на каждый релиз: сборка проверяется, но падение на этой платформе не блокирует выпуск. Для продакшена на RISC-V это ещё не зелёный свет, а сигнал, что можно начинать проверять свои колёса.

#cpython
Два класса с именем Helper в разных модулях затирают друг другу __value

Name mangling переименовывает __value в _Helper__value только по имени класса, без учёта модуля. Если два независимых класса Helper хранят __value, а кто-то наследуется от обоих, поле оказывается общим: один кладёт строку, другой число, сложение падает с TypeError. Именно этот пример сейчас обсуждают на форуме разработчиков Python в споре о настоящей приватности; рецепт на сегодня: одно подчёркивание и композиция вместо двойного наследования.

В нашем канале «Точка входа» разобрали подробнее.

@zen_of_python
1
Документация Python официально вышла на русском языке

Перевод объявлен официально и доступен на docs.python.org. Сделало его сообщество, и это тот случай, когда вклад волонтёров превращается в инфраструктуру языка.

Практический смысл двойной. Своим джунам теперь можно давать ссылку на официальную документацию, а не на пересказ с непонятной родословной. И при споре о терминологии появляется общая опора: как называется вещь по-русски, решает не переводчик статьи, а перевод самой документации.

Отставать от оригинала перевод будет ровно настолько, насколько его перестанут поддерживать, так что если найдёте кривое место, чинится оно пул-реквестом.
👍61
SpaceWeb исполнилось 25 лет — и вместо скучного пресс-релиза компания вместе с Типичным программистом сделала забавную анкету. Вопросы школьные: любимый спорт, лучший друг, обои на рабочий стол. А вокруг — аська, скайп, биткоин и всё остальное, чем жил рунет с 2001 по 2026 год, плюс короткая история веба и самой компании.

В конце — заглянем в будущее, дадим промокод на услуги SpaceWeb и покажем результат заполнения анкеты.
2👍1
Найти повторяющиеся строки просто, а вот решить, что считать одинаковым кодом, уже нет

Задача звучит тривиально: есть исходники, найди последовательности строк, которые встречаются больше одного раза. Автор Arid, чекера дублей для Python, начинал ровно с этой формулировки.

Ответ, как обычно, оказался «зависит от того, что вы имеете в виду». Переименованная переменная, другой порядок аргументов, вынесенный в константу литерал — текстуально это разный код, а по смыслу тот же самый.

Разбор интересен именно этим: как выбрать уровень абстракции, на котором сравнивать, и где проходит граница между дублем и совпадением. Полезно, если у вас в CI стоит проверка на дубли и вы не понимаете её вердиктов.
Автор написал токенизатор, RoPE и SwiGLU руками и обучил модель на бытовой видеокарте

Развернуть Unsloth и дообучить Llama 3 за вечер несложно. Автор захотел посмотреть, что будет, если так не делать, и написал всё сам: BPE-токенизатор, RoPE, блоки SwiGLU и цикл обучения на чистом PyTorch.

Получилась EmsyAI версии 4 на 196,7 млн активных параметров: около 180 млн в блоках трансформера, остальное в эмбеддингах словаря примерно на 16 тысяч токенов. Обучение прошло на 1,96 млрд токенов и на потребительской видеокарте.

Ценность тут не в качестве модели, а в том, что каждый слой написан руками и его видно. Если вы читали про RoPE и SwiGLU, но не собирали их сами, это готовый маршрут.
1
В Python шесть предобъявленных констант, и каждая ведёт себя по-своему

True, False, None, __debug__, Ellipsis и NotImplemented. Автор разбирает, чем они отличаются, и различий больше, чем ожидаешь.

Первая тройка это вообще не идентификаторы, а собственные лексические токены: разрешаются в лексере, а не при обычном разрешении имён. Побочный эффект в том, что выражение x.True даёт SyntaxError, и больше в языке так не ведёт себя ничего.

Отдельный случай __debug__: обычный идентификатор, но единственный, которому нельзя присвоить значение, причём даже как атрибуту. При этом x.__debug__ даёт уже AttributeError, потому что синтаксически это законно. Хорошая заметка на вечер, если любите тёмные углы языка.
1
EPUB это ZIP с XHTML внутри, и собрать его обратно после правки труднее, чем разобрать

Сервис LectuLibre переводит книги через модели: пользователь загружает EPUB, бэкенд достаёт текст, отправляет его в Claude или DeepSeek и кладёт перевод обратно в тот же файл. Автор пишет, что именно последний шаг оказался самым тяжёлым.

EPUB это ZIP-архив с документами XHTML, стилями, картинками, шрифтами и служебными файлами вроде container.xml и content.opf. Вернуть переведённый текст на место, сохранив форматирование, изображения, стили и метаданные, значит собрать валидный контейнер заново.

В разборе есть выбор библиотек и компромиссы, на которые пришлось пойти. Пригодится, если строите любой конвейер обработки электронных книг.
1
Что выбрать под неизменяемые объекты: обычный класс или dataclass

Обычный класс порождает изменяемые экземпляры, пока вы явно не запретите менять атрибуты. Отсюда и вопрос, который разбирает автор: где для неизменяемых данных проходит граница между ручным классом и dataclass.

В разборе три части: как сделать неизменяемость на голом классе, что даёт __slots__ для памяти и контроля атрибутов, и что из этого закрывает dataclass(frozen=True) без ручной работы.

Тема из тех, где каждый однажды принимает решение по привычке и живёт с ним годами. Хороший повод пересмотреть привычку на конкретных примерах.
🔥3
EVE Online начала переезд на Python 3 после двух десятилетий на второй ветке

Под каждым прыжком через гейт, каждым ордером на рынке и каждым флитфайтом в EVE лежит очень много Python. Он держит New Eden больше двадцати лет, и теперь CCP объявила о начале перехода на третью ветку.

Формулировка успеха у команды показательная: миграция должна пройти совершенно незаметно, если не считать моментов, когда что-то начнёт работать глаже. Первые шаги уже выкачены на тестовый сервер Singularity.

Это редкий публичный кейс переезда живого продакшена такого возраста. Обещают в итоге более быстрый поиск багов, место под новые фичи и общее ускорение, но дорога, по их же словам, длинная.
🤯5
Соберите первую нейросеть на Python без матана и видеокарты

Слово «нейросеть» звучит так, будто нужен продвинутый матанализ, мощная машина и тысячи строк кода. Ничего из этого не нужно.

На базовом уровне нейросеть это математическая модель, которая берёт на вход числа, что-то с ними считает, выдаёт предсказание, сравнивает его с правильным ответом и подправляет себя, чтобы в следующий раз ошибиться меньше. Этот цикл и есть обучение, всё остальное надстраивается сверху.

В туториале такую сеть строят руками на Python и NumPy, без фреймворков, чтобы был виден каждый шаг. Хороший следующий шаг после основ языка: слова «слой», «веса» и «обучение» перестанут быть заклинаниями и станут строчками кода, которые вы написали сами.

#python
4
Четыре джойна в SQL против одного запроса в графе: справочник по Neo4j и Python

Рамка задана вопросом, который легко произнести и тяжело написать: у каких инженеров есть свежий контекст по сервисам, задетым ночным инцидентом. В SQL это четыре или пять джойнов, каждый строит промежуточный результат шире нужного ответа и тут же выбрасывает большую часть. Запрос замедляется по мере роста таблиц и хуже читается с каждым возвращением к нему.

Справочник ведёт от пустой базы до работающего графа знаний: загрузка настоящих данных из Python и запросы, на которых идея становится понятной.

Разобраны части, которые туториалы пропускают: как решить, что становится узлом, почему первая модель данных почти наверняка неверна, как ускорить загрузку и как читать план запроса, когда что-то тормозит.
Соберите Discord-бота на Python и заодно разберитесь с асинхронностью

Со стороны бот выглядит сложно: отвечает на сообщения, помнит куски разговора, живёт круглосуточно. На деле это программа на Python, которая подключается к Discord, ждёт событие и решает, как на него ответить.

Как учебный проект он хорош тем, что за одного бота вы трогаете сразу несколько тем: команды, события, асинхронный Python, хранение состояния пользователя, переменные окружения и простейший деплой. Обычно это учат по отдельности и не видят, как оно соединяется.

Туториал начинает с совсем маленького бота и наращивает по одной функции. Каждый шаг можно запустить и увидеть результат, а не ждать финала.

#python
JIT в CPython перестанет быть экспериментом, если обгонит free-threaded интерпретатор на 20%

JIT лежит в main с 3.13, и включать его до сих пор незачем. В 3.15 он даёт 4–12% ускорения (среднее геометрическое по платформам Tier 1), отдаёт кадры, которые нативные отладчики разматывают в нормальный стек, и занимает меньше памяти под сгенерированный код, чем в 3.14.

PEP 836 называет цену выхода из статуса «экспериментальный»: к первой бете сборка с JIT и free-threading должна обойти free-threaded интерпретатор без JIT минимум на 20% по среднему геометрическому на pyperformance. Плюс совместимость, инструменты, дистрибуция и модель поддержки.

То есть JIT и free-threading перестают быть двумя отдельными экспериментами, их сводят в одну цель. Прогнать свои бенчмарки на сборке с JIT стоит сейчас, пока цифры в PEP обсуждаются.

#cpython
2😁1
Как выбрать между threading, asyncio и процессами, не переписывая код четыре раза

Модель конкурентности обычно берут ту, что уже стоит в соседнем модуле, а не ту, что подходит нагрузке. Пока задача упирается в сеть, ошибиться сложно: ждёт всё равно не процессор. На счётной задаче цена решения видна сразу.

В руководстве Real Python одна и та же задача написана в четырёх версиях: синхронной, на потоках, на asyncio и на процессах. И так дважды: сначала для нагрузки, где программа ждёт ответа по сети, потом для той, где она считает. Восемь реализаций одной задачи.

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

#python
4
Питонисту советуют TypeScript ради типов, которые у него уже есть

У питониста в CI давно стоит mypy, а аргументы за TypeScript ему перечисляют те же: типы ловят ошибки до запуска, интерфейсы фиксируют форму объекта, вывод типов экономит аннотации. Из этого набора собран и гайд для питонистов на dev.to.

Разница начинается дальше, в судьбе самих типов. В TypeScript они стираются при компиляции, и входящий JSON всё равно приходится проверять руками или через zod. В Python аннотации остаются в объекте: их читает pydantic, на них держится валидация в FastAPI, один и тот же тип работает и в проверке схемы, и в разборе запроса.

Одни считают, что после mypy в TypeScript идти незачем: тот же контракт, только с npm. Другие говорят, что tsc дисциплинирует сильнее mypy, который на чужом коде молча сдаётся на Any.

А по вашему опыту?

#python
ffmpeg вернул нулевой код возврата, а видео на выходе оказалось битым

Внешние утилиты из Python проверяют обычно одинаково: subprocess.run(..., check=True), и раз исключения нет, значит всё получилось. С ffmpeg этого мало: он спокойно отрабатывает с нулевым кодом и отдаёт файл, собранный не из тех фрагментов, которые вы просили, а заметить это можно, только досмотрев результат до конца.

В ReelCraft, CLI на Python для сборки ролика из папки с фото и видео, такое случилось трижды: Gemini 3.7 Flash разбирает ассеты и предлагает список нарезки, ffmpeg режет по нему, оба этапа отчитываются об успехе. Что именно разъехалось в склейке и субтитрах, разбирает дев-лог автора.

Приём оттуда полезен и без видео: между выводом модели и вызовом ffmpeg лежит edl.yaml, который человек читает и подтверждает руками. И проверять после subprocess стоит артефакт, тем же ffprobe, а не код возврата.

#python
Бэкап, украденный сегодня, расшифруют квантовой машиной через десять лет, и в Python от этого уже есть пакет

Зашифрованный архив можно скачать сейчас и спокойно подождать, пока появится машина, которая его вскроет: файлы на диске живут дольше, чем стойкость нынешних алгоритмов. На этот случай сделана библиотека Quipu: гибридное шифрование, где классическая схема X25519 и постквантовая ML-KEM-1024 работают вместе, так что контейнер откроется, только если падут обе сразу.

Питонисту она приезжает как pip install quipu-crypto, нативным колесом на PyO3; внутри Rust без сборщика мусора и без собственного unsafe. API короткий: encrypt_stream с decrypt_stream шифруют по паролю, generate_keypair с encode_to_recipient закрывают данные под конкретного получателя.

Заодно автор объясняет, почему из проекта исчезли слой C ABI и биндинги для Node и Go, которые были в первой версии.
😁3