Девман для питонистов
539 subscribers
159 photos
3 videos
206 links
Веб-разработка на Python. Канал от практиков.

Сайт школы Девман: https://dvmn.org/
Контакт для связи: @yulya_devman
Download Telegram
🤔 Давайте вместе разберемся, что не так с этим кодом?

for number, link in enumerate(response.json()['links']['flickr']['original'], start=1):
...


👉 Чтобы понять, что можно исправить, загляните в типичные улучшения Девмана.

➡️Делитесь своими ответами в комментариях!
Сложно понять, что происходит в коде, когда в одной строке выполняется сразу много операций: и вызовы функций, и сложение, и вычитание, и сравнение. Приходится распутывать выражение, мысленно разбирая его на части.

Код из нашего примера может выглядеть так:
image_links = response.json()['links']['flickr']['original']
for number, link in enumerate(image_links, start=1):
...


Если ответ на запрос будет еще где-то использоваться, то его следует закэшировать:

response = response.json()
image_links = response['links']['flickr']['original']
for number, link in enumerate(image_links, start=1):
...


По поводу обработки корнер-кейса с отсутствием значений в словаре: если применить метод get(), то получится нечто страшночитаемое вроде:
image_links = data.get('links', {}).get('flickr', {}).get('original', 'default.jpg')

При этом смысла продолжать работу функции, когда не удалось добраться до значений нет никакого — странно итерировать по значениям по умолчанию и пытаться что-то считать. Поэтому лучше воспользоваться перехватом исключением:
try:
image_links = response.json()['links']['flickr']['original']
except KeyError as exc:
raise CustomException() from exc


Итого — get() хорош, но все-таки когда одноуровневый словарь и есть реальное значение по умолчанию, которое можно и нужно использовать.

Но ошибка то может быть не только из-за пустого словаря…😱
try:
image_links = response.json()['links']['flickr']['original']
except (KeyError, json.JSONDecodeError, UnicodeDecodeError) as exc:
raise CustomException() from exc


Так что прикрутите Pydantic валидацию и выдохните!

Спасибо большое, что активно писали в комменты и предлагали свои варианты!❤️
🔥4
Вредные советы. Храните статусы в базе данных

Заказ. Такая привычная сущность в БД. Так хочется закинуть в админку статусы с выбором: выполнен, оплачен, подтвержден и т.д. Если «повезет», то таких статусов может стать 10, 20, 30… Статусы — это же так здорово и необходимо!


❗️Что получите:
– Никто не разберется в десятках статусов и они будут указываться рандомно;
– Поломку механизмов фильтрации данных по статусам, потому что см. пункт выше;
– Каждое значимое изменение статусной модели будет требовать недели для отладки дата миграций вашей продовой БД;
– Рефакторинг заблокирован, а костыли внутри проекта множатся в геометрической прогрессии.

✍️ Пример из жизни
Интегрировали платежную систему BetaTransfer в один из сайтов. 20 статусов у платежа в документации. Через 4 месяца эксплуатации узнали о 21-ом, которого не было в доке и техподдержка о нем тоже не знала. В общем товарищи накопили тот самый «балласт» статусной модели и потеряли контроль над ситуацией.


📌 Как дойти до жизни такой:
разработать статусную модель для объектов БД на старте,
развивать проект долго,
добавлять новые статусы под потребности бизнеса, не удаляя старые.

Может просто статусная модель неправильно была выбрана? Нет, ее в принципе нельзя сделать раз и навсегда в отличии от схемы данных, если она отражает предметную область (см. пост про DDD).

А можно удалить ненужные статусы? На них завязан старый код. Удалите — логика рассыплется как карточных домик.

❗️Статусы не являются частью предметной области, т.е. не существуют в реальности. Статусы зависят от контекста и привязаны не к объекту, а к связке Роль — Объект — Процесс. Менеджеру и Клиенту нужны разные статусы одного и того же заказа. Менеджеру нужны разные статусы заказа на разных этапах обработки.

Если Меняется структура команды, меняются бизнес-процессы → меняется набор необходимых статусов и завязанный на них код рассыпается. Если статусы есть в API — тем хуже. На них завязаны интеграции внешних сервисов и менять их совсем больно.

✍️ Как по-другому:

— Использовать и хранить в БД простые поля, привязанные к конкретным событиям: дата оплаты заказа, флаг заказ подтвержден или дата подтверждения заказа, дата доставки заказа и т.д.. Эти свойства существуют в реальности и они не изменятся со временем. Дата оплаты останется датой оплаты.

— Вынести статусы из слоя данных в слой представления, т.е. в фронтенд или хотя бы во вьюхи. Для каждого интерфейса у объекта вычислять нужные статусы на основе атомарных полей.

— Перестать воспринимать статус как строковый литерал: «выполнен», «доставлен». Важна не строка, а алгоритм вычисления. Т.е. статус на самом деле — это формула, а не сама строка. В итоге у вас могут появиться в интерфейсе (не в БД!) сложносоставные статусы вроде «одобрен вчера», «рекомендация Юли» и т.д.
🔥92😱1
Как не надо делать API

Каждый разработчик сталкивался с API, который ведет себя неожиданно и в итоге выжирает часы на отладку запросов-ответов и тестирование. Никого уже не удивишь вечным статусом 200 в API ВКонтакте, но это далеко не самый слабый вариант реализации.

В этом году в заказной разработке столкнулись с API Intrum CRM. И вот она разве что нервный срыв у разработчиков не вызвала. Создатели, кажется, совершили все ошибки при разработке API, которые существуют.

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

Некорректное использование GET и POST. Например, удалять записи в Intrum нужно через GET, а получать через POST. Взрыв мозга и бессонная ночь обеспечены.

Неполная или устаревшая дока. В итоге никто не знает что и как, пляшем с бубнами и гадаем что и куда подставить. Исходя из странной логики создателей (см. пункт выше), это тот еще квест, потому что все наоборот, как в королевстве кривых зеркал. Проблема решается автогенеренной документацией через OpenAPI + Pydantic в FastAPI или Django Ninja — там те же технологии под капотом.

Ошибки со статусом 200. Классика. Все бы ничего, но сервер честно кладет данные из запросов с ошибками в базу данных CRM. Отобразить в веб-интерфейсе при этом не может, т.к. ошибки. Итог — чего только в базе нет…

Кастомные поля. Доступны для каждого пользователя, объекта. Корректный вариант — когда доступные атрибуты перечислены и ограничены. Но в данном случае можно создавать любые кастомные поля через техподдержку. Вместо номеров и названий, у полей есть только идентификатор ID. Никто не знает что в этом поле лежит. Неизвестно что прилетит в ответе на любой запрос и что надо отправлять. ID по порядку выдают, судя по всему, уже четырехзначные пошли!

Божественный нейминг. Названия полей и их содержание вообще не совпадает. Например, поле «Автор» содержит имя ответственного менеджера. С числами тоже все плохо. Пользователь (User) содержит список сотрудников. А «Типы объектов» требуют строго один идентификатор.

Все поля ответа сервера опциональные. Так что даже если сервер и ответит, не факт что там будет хоть что-то или вы сможете расшифровать смысл.

Обязательные необязательные поля. Отправляешь запрос, а его не приняли. В запросе не хватает обязательного поля. Какого? Неизвестно. Что в нем должно быть? Неизвестно. В документации поле необязательное. Ну что, кто первый угадает чего не хватило?

✍️Делимся с вами, чтобы вы не повторяли их ошибок! Даже если ИИшка пишет за вас, вычитайте и позаботьтесь о тех разработчиках, которые будут с вашим API взаимодействовать.
🔥5😱5😢1
Ленты пестрят новостями о сокращениях, увольнениях джунов и «оптимизации» целых отделов. Кажется, что поезд ушел, и нейросети теперь сделают всю работу за нас. Зачем учиться, если через полгода тебя заменят кодом от ChatGPT?

Пока одни компании в панике режут штат, чтобы отчитаться перед инвесторами, другие делает ставку на будущее. Не сокращают, а именно нанимают новичков. Так, IBM утроила найм джунов и вот почему:

— Вместо краткосрочной экономии за счет замены людей ИИ, компания выбирает долгосрочную выгоду за счёт формирования кадрового резерва;

— ИИ меняет содержание работы, но не делает человека ненужным. Вместо рутинного написания кода, сотрудники будут уделять больше времени анализу, решению проблем и взаимодействию.

— Молодые сотрудники не обременены старыми привычками, готовы экспериментировать, задавать неудобные вопросы и быстрее осваивают новые инструменты.

— Больший эффект достигается при сотрудничестве опытных и молодых специалистов. Опытные привносят стратегическое видение и понимание контекста, а молодые — владение ИИ-инструментами и энергию для поиска новых решений.

— Главный риск сокращения найма джуниоров сейчас — это нехватка квалифицированных менеджеров и архитекторов через несколько лет. Невозможно вырастить руководителей, если не нанимать и не обучать молодых специалистов сегодня. ИИ не может выполнить эту задачу.

👉Мы изучили вакансии для Python-разработчиков на hh.ru и увидели, что, как минимум, в четверти из них требуются навыки работы с ИИ:
— В начале марта на hh.ru более 8000 вакансий с упоминанием Python;
— Если исключить слова, связанные с ИИ, то вакансий уже около 6000.

Получить навыки работы с нейросетями вы можете на наших курсах:
FastAPI: Создаем AI генератор сайтов с нуля
Курс по FastAPI: чат с ИИ за 4 часа

➡️А вы часто видите вакансии с требованием навыка работы с ИИ? Пишите о своём опыте в комментариях!
🔥3
Стоит ли верить слухам о «вымирании» Python

Несмотря на броские заголовки в СМИ вроде: «Python готовятся сбросить с первого места», язык все еще является одним из самых популярных и востребованных. Действительно, согласно февральскому рейтингу TIOBE, доля Python снизилась до 21.81% (пик был 26.98% в июле 2025).

Как ни странно, теснят Python «старички»: язык C (второе место) и специализированные языки вроде R (рванул с 15й на 8ю строчку) и Perl .

📌Вердикт TIOBE: несмотря на легкое охлаждение, Python остается королем горы с огромным отрывом от конкурентов. Это скорее нормализация после аномального взлета, чем катастрофа. Плюс есть некоторые вопросы к методике оценки рейтинга.

В отличие от опросов разработчиков, TIOBE использует косвенный метод. Он оценивает популярность языка по тому, как часто его название встречается в интернете:
Поисковые запросы. Индекс подсчитывает количество страниц, найденных по запросу +"<название языка> programming" (например, +"Python programming");

Источники данных. Поиск ведется не в одном, а в 25 крупнейших поисковых системах и популярных сайтах по всему миру;

Формула и веса. Результаты из всех этих источников не суммируются просто так. Каждому сайту присваивается свой вес (доля) в финальном результате, который зависит от его популярности.

✍️Итого индекс показывает не то, сколько кода написано на языке или сколько вакансий по нему открыто, а лишь «информационный шум» в интернете и подвержен следующим искажениям:
— Устаревший, но обильно представленный в сети язык может иметь высокие позиции;
— Метод сильно зависит от выбранных поисковых запросов;
— Рейтинги могут значительно колебаться от месяца к месяцу из-за изменений в алгоритмах поисковиков, а не из-за реального роста или падения популярности язык;
— Подверженность накруткам. Теоретически, рейтинг уязвим для искусственного завышения результатов сторонниками того или иного языка.

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

Если смотреть другие рейтинги с другими методами оценки — Python все равно в первой пятерке и исчезать никуда не собирается, так что продолжаем изучать и применять! Веб-разработка, интеграции с ИИ, ML, DataScience без него уже немыслимы.
👍1
⚡️ Перенесли курс «Введение в Python: онлайн-магазин» на сайт Девмана!

🌟Вы можете пройти этот курс у нас на сайте!

Чему вы научитесь:
— Запускать Python-скрипты и редактировать код в IDLE
— Создавать строковые объекты и работать с базовыми типами данных
— Импортировать модули и использовать встроенные функции вроде print()
— Применять условные операторы if elif else для построения логики программ
— Взаимодействовать с внешними сервисами через готовые фреймворки

Курс подойдёт даже тем, кто не написал ни одной строчки кода!

Давно мечтали стать Python разработчиком, но все ещё откладываете? Этот мини-курс для вас!

Результат за выходные — работающий бот для покупки мерча школы и первое код-ревью.

👉 Купить курс можно здесь

🌟А те, кто проходил курс «Введение в Python: онлайн-магазин в телеграм за 4 часа» на Stepik могут получить ревью по проекту!

👉 Чтобы получить код-ревью, напишите нам в Телеграм
🤔 Давайте вместе разберемся, что не так с этим кодом?
from datetime import datetime

datetime = datetime(2025, 1, 1, 0, 0, 0)

datetime = datetime(2025, 2, 1, 0, 0, 0)
print(datetime)

👉 Чтобы понять, что можно исправить, загляните в типичные улучшения Девмана
После такого объявления доступ к классу datetime пропадёт. Вместо него будет переменная с датой.

Код из нашего примера может выглядеть так:
from datetime import datetime

start_datetime = datetime(2025, 1, 1, 0, 0, 0)

end_datetime = datetime(2025, 2, 1, 0, 0, 0)
print(end_datetime)

❗️Избегайте использования зарезервированных оригинальных имён модулей, классов, функций и переменных. Их использование, возможно, не сломает код сразу, но позже может доставить много проблем.

Для получения всех встроенных имён выполните код в python:

import builtins
print(dir(builtins))
👍2
✍️Новые возможности генераторов списков

Генераторы списков или List Comprehension — мощный инструмент для высушивания и упрощения кода. Инструмент реализует упрощенный подход к созданию списка, который задействует цикл for, а также инструкции if-else для определения того, что в итоге окажется в финальном списке.

Было:
squares = []
for x in range(10):
squares.append(x ** 2)

Стало:
squares = [x ** 2 for x in range(10)]


Преимущества:
– Простота чтения: без циклов for и вложенности;
– Скорость. Быстрее for-циклов, которые он и заменяет;
– Неизменность данных. Исходные данные изменять опасно, а когда эти данные типа list или dict часто начинаются проблемы. List comprehensions создает новый список, не меняя исходный.

В шестом альфа-релизе Python 3.15.0a6 (февраль 2026) появилась реализация PEP 798Unpacking in Comprehensions. До сих пор мы могли распаковывать коллекции внутри литералов списков/словарей ([*a, *b]), но не могли сделать то же самое внутри comprehensions (генераторов списков). PEP 798 исправляет это.

👉Склейка вложенных списков
Раньше:
list_of_lists = [[1, 2], [3, 4], [5, 6]] 
flattened = [x for sublist in list_of_lists for x in sublist]

С новым синтаксисом:
list_of_lists = [[1, 2], [3, 4], [5, 6]]
flattened = [*sublist for sublist in list_of_lists]

👉Слияние словарей

Раньше: цикл с update.

С новым синтаксисом:
dicts = [{"a": 1, "b": 2}, {"b": 3, "c": 4}, {"d": 5}]
merged = {**d for d in dicts}
# {'a': 1, 'b': 3, 'c': 4, 'd': 5}

👉Генераторы

gen = (*range(i) for i in range(3))  # 0, 0, 1, 0, 1, 2

❗️Осторожно:
– В Python 3.15 эта фича пока в альфе. Использовать в продакшене рано, но тестировать уже можно!
– Синтаксис работает только на верхнем уровне выражения. То есть [*x for x in y] — ок, а [x for x in [*y]] (если бы это имело смысл) — нет;
– В асинхронных генераторах пока есть нюансы с yield from.
3🔥3
🐍 Сколько зарабатывает миддл Python-разработчик в 2026 году?

По данным Dreamjob средняя зарплата миддл Python-разработчиков с 2026 году — 233 000 рублей! Но рынок меняется быстрее, чем требования в вакансиях, поэтому хотим собрать актуальную статистику по зарплатам и грейдам среди Python-разработчиков!

Пройдите короткий анонимный опрос — это займет меньше минуты!
🤔Про использование ИИ мы сейчас слышим из каждого утюга. Но так ли эффективно внедрение искусственного интеллекта в процессы?

Согласно отчету MIT, 95% процентов пилотных проектов не влияют на результаты компаний.

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

✍️Вайб-кодинг (vibe coding)
— Что это: код генерируется быстро, но критерии приемки и гейты качества либо отсутствуют, либо формальны;
— Симптом: «работает у меня». На следующий день — регрессии, ломается сборка, растёт шум в ревью;
— Пример: агент «поправил авторизацию», но не обновил тесты и не проверил пограничные случаи. Вы узнаете об этом по падению в проде или по жалобам;
— Лечение: сначала сделать базовые гейты обязательными, потом поднимать глубину делегирования написания кода ИИ.

А вы используете ИИ-агентов в своей работе и насколько удовлетворены результатами? Пройдите, короткий опрос, который займет меньше минуты! Рассказывайте о проблемах, с которыми сталкиваетесь при использовании ИИ, в комментариях!

Если ответов будет много, мы запостим еще две ловушки, с которыми сталкиваются разработчики!
Вы используете ИИ-агентов для разработки программных продуктов?
Anonymous Poll
24%
Нет, не использую
37%
Да, но не часто
36%
Да, часто
3%
Полностью отдал написание кода ИИ
Сталкивались с проблемами при использовании ИИ для разработки программных продуктов?
Anonymous Poll
12%
Нет, проблем нет
40%
Да, иногда бывают проблемы
37%
Да, проблем много
12%
Быстрее сделать самому ручками
Видим, что вы часто сталкиваетесь с проблемами при использовании ИИ в разработке. Мы уже писали о первой ловушке, которая мешает разработчикам научиться использовать ИИ в разработке. Сегодня поделимся еще двумя.

✍️Ложная автономность (proxy autonomy)
— Что это: кажется, что «агент делает», но вы всё продумываете за него;
— Симптом: чтобы получить результат, вы пишете слишком подробные инструкции до уровня «вот в этом файле поменяй эту функцию». Быстрее было бы сделать руками;
— Пример: задача выглядит как «сделай фичу», а по факту вы диктуете агенту пошаговый рецепт, потому что без него он не попадает в архитектуру.
— Лечение: поднимать глубину делегирования кодинга там, где можно описать ценность и критерии приемки, а не технические шаги. Инвестировать в контракты (например, схему API) и шаблоны задач.

✍️Разрастание скоупа (scope explosion)
— Что это: агент начинает «улучшать всё подряд»: правит форматирование, переименовывает, меняет архитектуру, добавляет лишние зависимости;
— Симптом: слишком большой набор изменений без понятной цели, много побочных правок, сложно ревьюить;
— Пример: вы попросили «починить баг», а агент параллельно переименовал половину модулей и заменил библиотеку логирования;
— Лечение: жесткие рамки (что трогаем/не трогаем), лимит на размер изменений, стоп-правила («остановись и спроси»), приоритет «минимальное изменение, которое дает ценность».

— Дополнительно: ввести бюджет код-ревью (Code Review Budget): лимит времени и внимания на ревью, под который подгоняете объем изменений;
— Дополнительно: фиксировать архитектуру и ценность ее компонентов, чтобы агент не «оптимизировал» то, что трогать нельзя.

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

👉А с какими еще ловушками при использовании ИИ-агентов вы сталкивались? Делитесь в комментариях!
🤔 Давайте вместе разберемся, что не так с этим кодом?
...
for vacancy in response.json()['items']:
...
pages = response.json()['pages']
...

👉 Чтобы понять, что можно исправить, загляните в типичные улучшения Девмана.

➡️Пишите в комментариях, что можно исправить!
Превращение JSON строки в структуру данных Python требует много процессорного времени. Этот ресурс не безграничен, поэтому нельзя допустить, чтобы программа транжирила его на неоправданно частые вызовы метода response.json().

Код из нашего примера может выглядеть так:
...
payload = response.json()
for vacancy in payload['items']:
...
pages = payload['pages']
...


Спасибо большое, что активно писали в комменты и предлагали свои варианты!
🔥3