Комментарии 23
Очень сильно пахнет ГПТшкой (оформление триггернуло), два - а разве мысль о том, что хранить состояния в строках и использовать фиксированные значения больше, чем в одном месте - это скорее плохо, не очевидная? Впрочем, сам не питонист. Если нужны именно строки для состояний - проще тогда завести класс с константами и там их хранить, и никаких проблем.
По поводу оформления — справедливо, привычка структурировать всё по полочкам иногда делает текст похожим на мануал :)
Насчет "очевидности" — вы правы, это база. Но, как показывает аудит чужого кода, "база" — это то, на чем чаще всего сыплются.
Почему не просто класс с константами? Можно и так, но Enum в Python — это не просто группировка. Это защита от дублирования значений, возможность типизации и удобная работа с именами/значениями (name/value) без костылей. Для простых скриптов константы ок, для чего-то сложнее — Enum безопаснее
С константами есть проблема - IDE/typechecker не станет ругаться, если не покрыть все значения. С перечислениями(Enum/Literal/Union - неважно), ситуация принципиально иная. Например:
Константы без else ветки
FAIL = 1
SUCCESS = 2
PROCESSING = 3
def process(status: int) -> str: # typechecker ругается, что не во всех случаях возвращается строка
if status == FAIL:
return 'fail'
elif status == SUCCESS:
return 'success'
elif status == PROCESSING:
return 'processing'
В этом случае тайпчекер будет ругаться, так как не все возможные значения для status покрыты. Придётся добавить ветку else. Мало того, что нужно будет как-то обработать невозможное значение для status, так ещё и в случае появления новой константы для статуса, мы никак не узнаем, что не обработали её.
В случае же с перечислениями, мы не обязаны иметь ветку else и ещё до запуска узнаем о том, что не обработали одно из возможных значений для статуса. Пример:
Перечисления без else ветки
class Status(enum.Enum):
FAIL = enum.auto()
SUCCESS = enum.auto()
PROCESSING = enum.auto()
def process_status(status: Status) -> str: # всё в порядке, typechecker знает, что мы обработали все возможные значения
if status is Status.FAIL:
return 'fail'
elif status is Status.SUCCESS:
return 'success'
elif status is Status.PROCESSING:
return 'processing'
Автор каждые несколько дней выдает очередной опус, маловероятно что он сам это пишет
Лишние метафоры, спискота, эмодзи в заголовках... 100% генеративщина ради ссылки на телеграм.
Можно перейти к классам с общим интерфейсом.
Тогда будет позднее связывание, и в случае добавления статуса нужно будет добавить новый класс, а не делать изменение в двух местах. В случае изменения это изменение тоже будет в одном месте.
О повеяло Бобом Мартином и его магическими числами, правда гораздо более многословно.
Но вы правы, использовать строчные литералы в коде - плохая идея, но это больше ошибка новичков, общая рекомендация в том же Python, использовать Enum. К примеру в документации FastAPI https://fastapi.tiangolo.com/tutorial/path-params/#predefined-values
товарищ, не ленись писать статьи ручками!
А что вам не понравилось в статье? Или может вы с чем то не согласны в статье? Не ленитесь как то аргументировать вашу позицию)
Вы первый раз на Хабре? Когда-то тут было много контента, в который авторы вкладывали души, который представлял ценность. Еще остались воспоминания о тех славных временах. По этой причине тут не ценится нейрогенерация. Особенно по избитым темам.
А что вам не понравилось в статье
То, что статья - плод творения ллм
Статья не понравилась тем, что Вы здесь, как автор, лишний. У вас здесь просто сырая выдача LLM, которую каждый может получить за минуту. Статья не несет следа Вашей компетенции. Но в эту статью вы не забыли добавить ссылку на свой телеграм-канал. При том, что непонятно, чем он может быть ценен. Другими копипастами из LLM? Потому что, повторюсь, статья, при ее технической корректности, Вашу экспертность скорее антиутверждает
Обычный
Enum— штука классная, но строгая. Если ты создашьOrderStatus.PENDING = 1, а потом попробуешь сравнить его просто с числом (if status == 1), Python скажет: «Э, нет, это разные вещи!». Для него объект перечисления не равен числу, даже если внутри него спрятана единица.Но в реальности мы часто получаем данные из баз данных или через API в виде обычных чисел. И тут на сцену выходит IntEnum.
И правильно питон скажет. При получении из апи вы должны провалидировать данные и сконвертировать в ваш энум, а не забивать на смысл энума разрешая его использовать вместе с интом. Энум обычно предполагает совершенно другие сценарии использования чем обычный int. И если где-то вам надо конвертировать одно в другое - там по месту и конвертируйте
Жалко, что в питоне нету встроенной поддержки enum на уровне синтаксиса, как в C++, к примеру. А то так выходит много абстракций и всё-таки это чуть более громоздко.
Код на «магических строках»
Погодите, так реально что ли пишут на питоне? И там что, нет поддержки enum из коробки, что вот это всё надо городить? Или это какой-то галюциногенный угар от чатжпт?

Python: Почему строки в if-else — это плохо, переходим на Enum