Русский
Открыть в Telegram
ZZen of Python

Zen of Python

✅ Высокое доверие
@zen_of_python · канал · Технологии · в индексе с 2026-05-02
18 766подписчиков−1 за неделю
1 031средний охват поста
5.5%ER — охват к подписчикам
66постов за 30 дней
Zen of Python
Фотография
нажмите — покажем
Как запустить урезанный Python в браузерной песочнице Monty от Pydantic исполняет небольшой Python-подобный язык внутри приложения. Интерпретатор написан на Rust для кода, который генерируют языковые модели: файловая система, переменные окружения и сеть недоступны, а функции хоста вызываются только с разрешения разработчика. Саймон Уиллисон собрал Monty для WebAssembly как модуль JavaScript и Python-пакет для Pyodide: получается песочница внутри песочницы. Поддерживается часть синтаксиса, пока без классов. В разборе в Simon Willison’s Weblog есть команды сборки, устройство вариантов и браузерные демо.
3 · 1.4K ·
Фотография
нажмите — покажем
Как исправить вызов NamedTuple в Python 3.15 В Python 3.15 больше не поддерживается создание NamedTuple через именованные аргументы полей. В версиях 3.13 и 3.14 такой код выдаёт предупреждение об устаревании. Этот синтаксис никогда не был документирован и работал лишь потому, что старая реализация принимала произвольные именованные аргументы. «Явное лучше неявного» здесь стало требованием интерпретатора. Исправить код можно двумя способами: объявить класс, наследующий NamedTuple, или передать в функциональную форму список пар «имя, тип». Классовый вариант читается проще и оставляет место для методов и строк документации. Ruff 0.16 автоматически переводит обе формы в классовую по правилу UP014: достаточно запустить ruff check --fix. Для старых версий правило нужно включить отдельно. Примеры обоих исправлений есть в разборе Адама Джонсона.
6 · 1.3K ·
Z
Фотография
нажмите — покажем
Как читать многострочный ввод в Python REPL несколько раз Вызов open(0).read() читает стандартный ввод до конца потока и сохраняет строки вместе с переносами. Для завершения ввода нажмите Ctrl+D в Unix или Ctrl+Z в Windows. Повторный вызов заканчивается ошибкой OSError: после первого чтения Python закрывает файловый дескриптор 0. Передайте closefd=False, и стандартный ввод останется доступен: open(0, closefd=False).read() можно вызывать снова. Явный параметр здесь действительно лучше неявно закрытого ввода. Приём пригодится, когда в интерактивной сессии нужно последовательно прочитать несколько блоков текста. Два таких чтения показаны в разборе TIL #139.
4 · 1.3K ·
Zen of Python
Фотография
нажмите — покажем
Как emojet ускоряет работу с эмодзи в Python Библиотека emojet преобразует названия в эмодзи и обратно, поддерживает поиск и закрывает основное API пакета emoji. Имена доступны на 14 языках, а также в вариантах, принятых в GitHub и Slack. В тестах автора на Python 3.14 для macOS и ARM импорт оказался в 23,7 раза быстрее, преобразование эмодзи в названия в 69,9 раза, обратная операция в 3,5 раза. Импорт с первым вызовом использовал около 17,4 МБ памяти вместо 29,2 МБ у emoji. Раньше emoji при импорте загружал и разбирал JSON-файл размером 520 КБ. emojet написан на Rust и хранит данные в скомпилированных статических таблицах: разбирать файл при запуске не нужно. Для поиска имён используется хеш-таблица без коллизий, а для распознавания последовательностей эмодзи — дерево символов. В статье разобраны устройство библиотеки и воспроизводимый тест производительности.
7 · 1.3K ·
Фотография
нажмите — покажем
Как запускать Python-код в песочнице на MicroPython и WebAssembly В проектах Саймона Уиллисона плагины получают все права основного приложения: ошибка или вредоносный код могут повредить данные. Пакет micropython-wasm переносит интерпретатор MicroPython в WebAssembly и изолирует выполнение. Память ограничивает wasmtime, а процессорное время контролирует «топливо»: запас операций, после исчерпания которого выполнение прекращается. Файлы, сеть и функции основного приложения доступны только через явно выданные интерфейсы. Состояние между вызовами сохраняет сессия с отдельным потоком и очередями запросов. Пакет уже опубликован на PyPI, но пока имеет статус альфы: автор использует его сам, однако не рекомендует без готовности принять существенный риск. Архитектура, ограничения и команды для запуска разобраны в Simon Willison’s Weblog.
7 · 1.3K ·
Z
Фотография
нажмите — покажем
Почему Python предупреждает о последовательности \477 и как это исправить В строках Python обратная косая черта и до трёх цифр от 0 до 7 задают восьмеричный код символа. Значение \477 равно 319 и выходит за предел 255, для которого такие последовательности задумывались. В обычной строке оно превращается в символ Ŀ, а в байтовой строке обрезается до 63 и даёт знак вопроса. Не самый явный способ записать путь. В Python 3.11 предупреждение DeprecationWarning можно было увидеть в режиме разработки. Начиная с Python 3.12 компилятор выдаёт SyntaxWarning и без него; позднее конструкция должна стать синтаксической ошибкой. Если косая черта в пути или регулярном выражении должна остаться символом, удвойте её: \\477. Если восьмеричный код был намеренным, укажите нужный символ явно. Механику и различие между str и bytes автор разбирает в статье Adam Johnson.
4 · 1.3K ·
Zen of Python
Фотография
нажмите — покажем
Как вручную разрешить ленивый импорт в Python У объекта, созданного через lazy import json, есть метод resolve(). Его можно обнаружить с помощью dir(globals()["json"]), а справка поясняет: метод разрешает ленивый импорт и возвращает настоящий объект модуля. Вызов globals()["json"].resolve() возвращает модуль json, но имя в глобальном пространстве по-прежнему указывает на объект lazy_import. Автор предполагает, что при автоматическом разрешении Python вызывает тот же метод, а затем присваивает имени полученный модуль. В этот раз «явное лучше неявного» можно понимать буквально. В разборе показано, как исследовать этот механизм через dir() и help(); открытым остаётся вопрос, что именно запускает автоматическое разрешение импорта.
5 · 1.2K ·
Фотография
нажмите — покажем
Почему str.splitlines() видит больше переносов, чем чтение файла У Python два разных понятия границы строки. Универсальный режим чтения файла распознаёт LF, CR и CR LF. str.splitlines() шире: десять отдельных кодовых точек плюс CR LF. Туда входят вертикальная табуляция, перевод страницы, разделители строки и абзаца Unicode и три ASCII-разделителя данных. Python собрал этот набор из правил ASCII, Unicode-переносов и двунаправленного текста. За простым методом стоят несколько наборов символов и пять документов Unicode. История всех разделителей полезна при обработке внешнего текста: символ, задуманный как граница записи, может стать границей строки. Поэтому сначала сверяйте формат входа, а потом выбирайте чтение файла или splitlines().
4 · 1.1K ·
Z
Фотография
нажмите — покажем
Как собирать динамические фильтры Django через Q-объекты Q() представляет условие для SQL-запроса. Такие объекты можно объединять операторами & и |, отрицать через ~ и передавать в один вызов filter(). Это позволяет явно задать, какие условия должны выполняться вместе, а какие служат альтернативами. В примерах с Q-объектами поисковая строка разбивается на слова, для каждого строится проверка icontains, а затем условия соединяются через OR. Для небольших наборов данных этого достаточно, но на больших SQL-запросы с OR могут работать медленно. Фильтры можно вынести в функции или методы моделей и собирать из пользовательских параметров. Автор предпочитает один filter(): так вся логика запроса видна в одном месте и проще контролировать JOIN при обходе связей. Явное условие лучше неявной цепочки, почти по PEP 20.
3 · 1.2K ·
Zen of Python
Ссылка
нажмите — покажем
Как заменить цепочку isinstance на singledispatch Когда обработка типов разрастается, цепочка isinstance() превращает одну функцию в дерево условий. Декоратор functools.singledispatch оставляет единый интерфейс, а реализации для отдельных типов регистрируются независимо. Выбор происходит по типу первого аргумента. Учитывается и наследование: регистрация для Mapping подходит обычному dict через порядок разрешения методов. Обратная сторона той же механики: bool наследуется от int, поэтому для иной семантики ему нужен отдельный обработчик. Аннотация помогает register() определить тип, но list[str] и list[int] не становятся разными случаями во время выполнения. В разборе singledispatch также показано, как тестировать обработчики отдельно, проверять выбор через dispatch() и проектировать явный fallback.
7 · 1.2K ·
Фотография
нажмите — покажем
Как разделить синхронный и асинхронный Python-клиенты При переписывании akismet автор отказался от одного класса с обычными и асинхронными методами. Клиент проверяет ключ API при создании, а для этого нужен HTTP-запрос. Синхронный запрос заблокировал бы асинхронный код, а запуск проверки через async потребовал бы заранее выбрать и получить работающий цикл событий. Решением стали отдельные SyncClient и AsyncClient. Заодно новые имена позволили оставить прежний класс Akismet устаревшим, но рабочим, чтобы пользователи могли перейти без немедленной поломки API. Названия скучные, зато состояние клиента и способ ввода-вывода больше не приходится угадывать. Разбор переписывания библиотеки также показывает, почему набор функций оказался хуже класса: ключ, адрес сайта и результат их проверки пришлось бы хранить в скрытом общем состоянии.
7 · 1.2K ·
Z
Фотография
нажмите — покажем
Как запускать собственный SQL через миграции Django У models.Index нашлось необычное применение: его подкласс можно добавить в Meta.indexes, чтобы Django включил объект в автоматически созданную миграцию. При её выполнении фреймворк получит SQL из методов create_sql и remove_sql. Так к схеме таблицы можно привязать, например, комментарии или триггеры. В django-security-label этот механизм задаёт правила анонимизации PostgreSQL прямо рядом с полями модели. Когда модель меняется, система миграций добавляет или удаляет соответствующие метки в схеме. Получается явно и рядом с предметной моделью, хотя автор прямо называет приём хаком. Разбор механизма и пример с анонимизацией помогут оценить границы подхода. SQL из упрощённого примера копировать нельзя: он не экранирован должным образом.
4 · 1.4K ·
Zen of Python
Фотография
нажмите — покажем
Как проверять инварианты Python-кода с Hypothesis Обычный тест фиксирует конкретный ввод и ожидаемый результат. Hypothesis предлагает описать свойство, которое должно выполняться для всех подходящих данных, а затем генерирует сотни вариантов. Явные инварианты лучше неявного каталога крайних случаев. С @given и стратегиями можно проверять идемпотентность, сериализацию с обратным преобразованием и ограничения коллекций. Если свойство нарушено, Hypothesis упрощает вход до минимального контрпримера: вместо строки на тысячи символов остаётся значение, на котором удобно отлаживать код. Практический разбор Hypothesis показывает стратегии генерации и интеграцию с pytest. Такие проверки дополняют обычные тесты, а найденную регрессию лучше закрепить отдельным тестом или @example.
12 · 1.4K ·
Фотография
нажмите — покажем
Как коллизии превращают построение set в Python в квадратичную задачу Привычное O(1) для set и dict предполагает, что коллизии редки. Если много ключей получают одинаковый хеш, интерпретатору приходится искать свободные ячейки и перебирать кандидатов при проверке вхождения. O(1) здесь полезная модель, а не договор с интерпретатором. В эксперименте с подобранными целыми числами удвоение размера почти учетверяло время: построение множества из 16 000 элементов заняло 1072 мс, а из 100 000 — 45 секунд. Проверка всех элементов росла так же. Отдельно автор измерил влияние процессорного кеша: поиск случайных строк в dict замедлялся по мере роста таблицы даже без коллизий. Это другой механизм, поэтому при неожиданной деградации стоит отдельно проверять распределение хешей и размер данных.
10 · 1.4K ·
Z
Ссылка
нажмите — покажем
partial или lambda: как специализировать колбэк без сюрпризов functools.partial заранее связывает часть аргументов и возвращает вызываемый объект. Сохранённые именованные аргументы работают как значения по умолчанию: при вызове их можно переопределить. Проверки новой сигнатуры при этом нет, поэтому повторная передача одного параметра закончится TypeError. Разница с lambda проявляется во времени связывания. Лямбда получает текущее значение имени при выполнении, а partial сохраняет переданный объект при создании. Но копии не делает: изменения связанного списка будут видны, а долгоживущий колбэк удержит контекст в памяти. Сравнение двух способов специализации функций сводится к питоничному правилу: если нужно только связать аргументы, подходит partial. Если адаптер проверяет данные, логирует или преобразует аргументы, яснее написать именованную функцию через def.
7 · 1.3K ·
Zen of Python
Фотография
нажмите — покажем
Как OpenBLAS ускоряет NumPy в браузере Раньше браузерная сборка NumPy выполняла np.matmul обычными циклами на C, которые не учитывали кэш процессора и векторные инструкции. Теперь NumPy 2.5.3 из Emscripten-forge по умолчанию подключает OpenBLAS 0.3.34 для WebAssembly. На квадратных матрицах 1024 × 1024 умножение ускорилось примерно в 30,92 раза для float32 и в 14,90 раза для float64. Прирост зависит от операции. Функции np.linalg ускорились слабее, поскольку реализация LAPACK ещё не оптимизирована специально для WebAssembly. Экспериментальная OpenBLAS 0.3.35 добавляет новые векторные ядра, а сборка с Relaxed SIMD даёт дополнительное ускорение только в браузерах с поддержкой этого расширения. Бенчмарки и настройки стенда помогают сравнивать сборки по размеру матриц, типу данных и браузеру, а не переносить одну красивую цифру на весь NumPy.
3 · 1.3K ·
Фотография
нажмите — покажем
Как проверять плагины через контракт Pydantic и FastAPI Сервис может отвечать по нужным адресам и всё же возвращать несовместимые данные. В схеме общего API-контракта модели Pydantic для /ready, /catalog и /encode/ вынесены в отдельный пакет. Плагин использует эти модели в обработчиках FastAPI, а платформа проверяет ими ответы при регистрации. Если структура не совпадает, сервис не подключается. Контракт фиксирует и ответственность: разбиением входных данных управляет плагин, а проверки доступа вынесены в зависимости FastAPI. Это ловит несовместимый формат до подключения, но не проверяет правильность вычислений.
6 · 1.4K ·
Z
Фотография
нажмите — покажем
Как битовые множества сокращают память моделей Pydantic Explicit is better than implicit, но хранить набор явно переданных полей в полноценном Python set оказалось накладно. Memray показал: создание model_fields_set заняло почти 800 МБ на миллионе экземпляров модели с семью полями. Поскольку поля модели упорядочены, каждому можно назначить номер бита: 1 означает, что значение передали при создании, 0 — что использовано значение по умолчанию. Имена дополнительных полей, которых нет в схеме, остаются в отдельном set. В разборе реализации показано, как выбирать u8, u16 или вектор для моделей разного размера. На тесте с небольшими значениями замена сократила память на 55%. Полезный пример того, почему профилировать стоит не только __dict__, но и служебные структуры каждого экземпляра.
7 · 1.4K ·
Zen of Python
Фотография
нажмите — покажем
Как отменять задачи в heapq и сохранять порядок при равных приоритетах heapq сравнивает кортежи по полям. Поэтому запись (приоритет, задача) при равных приоритетах либо сравнит сами задачи, либо упадёт, если объекты несравнимы. Надёжная форма: (приоритет, номер, задача), где номер выдаёт itertools.count(). Он сохраняет порядок добавления и не допускает сравнения задач. Искать и удалять произвольную запись по идентификатору куча эффективно не умеет. Для отмены и смены приоритета можно хранить активные записи в словаре: старую помечать удалённой, новую добавлять в кучу, а помеченные пропускать при извлечении. Лень здесь вполне питонична. У этой схемы очереди есть цена: устаревшие записи занимают память, пока не доберутся до вершины. Если обновлений много, а извлечений мало, кучу стоит периодически пересобирать из активных записей.
8 · 1.3K ·
Фотография
нажмите — покажем
Как воспроизводить гонки потоков Python с помощью blanket Обычно порядок выполнения потоков выбирает ОС, поэтому редкая гонка превращает тест в лотерею. blanket оборачивает примитивы threading, а тест сам решает, какой поток продолжит работу. Пять повторов перестают быть стратегией тестирования. В Scenario можно заставить поток B захватить блокировку раньше A, задать порядок освобождения барьера или выбрать поток, который разбудит notify(). Каждый такой вызов приостанавливается в планировщике blanket, поэтому сценарий повторяется одинаково. Это полезно при переносе библиотек на Python без GIL, но управление порядком потоков работает на границах примитивов синхронизации. Для гонки внутри голого counter += 1 нужна дополнительная контрольная точка. blanket закрепляет известный порядок в регрессионном тесте, а не перебирает все возможные гонки.
6 · 1.2K ·
Z
Ссылка
нажмите — покажем
Пакетная обработка в Python: где strict=True не спасает запись С Python 3.12 itertools.batched() лениво забирает из итератора элементы только для очередного кортежа. Поток из файла, курсора или генератора не приходится сначала превращать в список: памяти для группировки нужно столько, сколько занимает один пакет, а не весь источник. С Python 3.13 параметр strict=True отклоняет неполный последний пакет. Но ошибка возникает во время итерации. При 250 записях и размере пакета 100 первые 200 уже могут попасть в базу, прежде чем оставшиеся 50 вызовут ValueError. Строгость проверяет форму входа, а не делает цикл транзакцией. Явное лучше неявного: для записи по принципу «всё или ничего» заранее проверьте конечный источник либо используйте транзакцию системы назначения. Разбор itertools.batched() также объясняет, почему list(batched(...)) лишает обработку преимущества ленивости.
5 · 1.4K ·
Zen of Python
Фотография
нажмите — покажем
Как выстроить защиту цепочки поставок Python Эшелонированная схема защиты начинается с собственного кода: Ruff находит секреты, слабую криптографию и запросы без тайм-аута до публикации пакета. Зависимости и их криптографические хеши фиксируют через uv lock или uv pip compile --generate-hashes. Затем pip-audit ищет в CI известные уязвимости, а SBOM помогает понять, затронул ли проект компрометированный пакет. Trusted Publishing с OIDC заменяет долгоживущие API-токены. Хеши не распознают изначально вредоносный пакет, а аудит пропускает неизвестные уязвимости. Поэтому начать стоит с Ruff и фиксации зависимостей, затем добавить аудит и SBOM.
9 · 1.4K ·
Z
Ссылка
нажмите — покажем
Как не сломать pickle собственным исключением Python Если конструктор исключения принимает field и reason, не заменяйте их готовой строкой при вызове super().__init__(). Иначе в args останется один элемент, а при восстановлении BaseException.__reduce__ передаст его обратно конструктору. Тот ждёт два аргумента, поэтому распаковка завершится TypeError. Так же ломаются copy.copy() и передача исключения между процессами. Питоничный инвариант прост: args должны оставаться корректным списком аргументов для вашего __init__. Передавайте в базовый класс исходные field и reason, храните структурированные данные в атрибутах, а читаемое сообщение формируйте в __str__. Пример с ValidationError показывает поломку и совместимый вариант класса.
2 · 1.7K ·
Z
Zen of Python
Ссылка
нажмите — покажем
Охрана трубопровода длиной 400 километров Камеры на столбах не заглянут за угол, дрон висит 30-40 минут и летит заряжаться, а охранник-человек — дорого, медленно и небезопасно на протяжённом объекте. Технический разбор робопса изнутри: что скрыто под закрытым ядром биомеханики, какой стек сенсоров закрывает слепые пятна друг друга — лидар боится стекла, поэтому рядом ставят сонар. Как рой из нескольких собак строит p2p-сеть, чтобы одна работала мостом для другой за горизонтом связи в техническом разборе робопса.
7 · 1.7K ·
Z
Zen of Python
Фотография
нажмите — покажем
Как вернуть значение из всплывающего окна в форму Django Admin Django Admin умеет создавать связанный объект во всплывающем окне и сразу подставлять его в исходную форму. Практический разбор этого механизма показывает, как переиспользовать его для собственного инструмента выбора значений. Пример связывает ModelAdmin, отдельное представление, URL и шаблон. Ссылка вызывает showRelatedObjectLookupPopup, а кнопка во всплывающем окне через opener.dismissRelatedLookupPopup возвращает выбранную строку в поле формы и закрывает окно. Питоничность здесь в композиции готовых частей: представление может вычислить значение любым способом, а JavaScript админки доставит результат в нужное поле. Цена переиспользования — зависимость от соглашений Django Admin: специального идентификатора ссылки и функций из RelatedObjectLookup.js.
4 · 1.7K ·

Открытая публичная лента из поискового индекса ChatCrawler — «Google по публичному Telegram»; обновляется по мере обхода площадки. Время — UTC.

Только публичный контент, официальный API Telegram. О проекте · Вопросы · Границы индекса · Убрать страницу из выдачи · Каталог · Поиск · Как мы считаем