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

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

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

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

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

Регистрация в перечне РКН: https://tprg.ru/xZOL
Download Telegram
Кто закроет async-генератор после break

Вы читаете поток до первого подходящего элемента и выходите через break. Цикл закончился, но сам по себе этот выход не гарантирует немедленное выполнение finally у async-генератора. Если там освобождается ресурс, его срок жизни лучше задать явно.

В Python 3.10+ для этого есть contextlib.aclosing. Оберните генератор в async with, как на карточке. При выходе из блока менеджер вызовет await generator.aclose(), в том числе после раннего выхода или исключения.

Очистка пройдёт в том же контексте, что и перебор. Это существенно, если она использует контекстные переменные или зависит от ещё работающей задачи. В примере из документации очистка выполняется при выходе из блока, без ожидания сборки мусора.
🔥1
NewType различает ID без новых объектов

Идентификаторы пользователя и заказа могут быть обычными int, но случайно поменять их местами всё равно ошибка. UserId = NewType("UserId", int) позволяет описать это различие для статического анализатора.

Функция с параметром UserId принимает UserId(42), а на голое 42 проверяющий должен пожаловаться. В обратную сторону преобразование не нужно: UserId допустим там, где ожидается int. После арифметики вроде UserId(5) + 1 статический тип результата снова int.

Во время выполнения вызов возвращает тот же объект. Это отдельный тип для проверяющего, а не валидатор входных данных и не runtime-подкласс. Использовать его вторым аргументом isinstance нельзя. Проверку внешнего ID всё ещё придётся написать.