Обновить

Комментарии 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% генеративщина ради ссылки на телеграм.

так и есть, статья ради статьи. уникальности 0. на хабре уже есть хорошая статья по enum, и она более подробнее описывает.

а не кучу воды вокруг "вы можете теперь не передавать сухие строки и мэджик числа в условия, радуйтесь"

Можно перейти к классам с общим интерфейсом.

Тогда будет позднее связывание, и в случае добавления статуса нужно будет добавить новый класс, а не делать изменение в двух местах. В случае изменения это изменение тоже будет в одном месте.

автор не знает что это, ему как гпт написал он так и сделает

Новый класс ради одной строчки? Я вас поавильно понял?

Ну не новый модуль же, класса будет достаточно.

О повеяло Бобом Мартином и его магическими числами, правда гораздо более многословно.

Но вы правы, использовать строчные литералы в коде - плохая идея, но это больше ошибка новичков, общая рекомендация в том же Python, использовать Enum. К примеру в документации FastAPI https://fastapi.tiangolo.com/tutorial/path-params/#predefined-values

Использовать магические константы в коде плохо, это все знают. Поэтому настоящие программисты пишут так:
#define MAGIC_ZERO 0
#define MAGIC_ONE 1
и так до 30, что ли. Реальный код непомню где, у analog devices возможно

товарищ, не ленись писать статьи ручками!

А что вам не понравилось в статье? Или может вы с чем то не согласны в статье? Не ленитесь как то аргументировать вашу позицию)

Вы первый раз на Хабре? Когда-то тут было много контента, в который авторы вкладывали души, который представлял ценность. Еще остались воспоминания о тех славных временах. По этой причине тут не ценится нейрогенерация. Особенно по избитым темам.

А что вам не понравилось в статье

То, что статья - плод творения ллм

аргумент)

собственно на этом всё

понял

Статья не понравилась тем, что Вы здесь, как автор, лишний. У вас здесь просто сырая выдача LLM, которую каждый может получить за минуту. Статья не несет следа Вашей компетенции. Но в эту статью вы не забыли добавить ссылку на свой телеграм-канал. При том, что непонятно, чем он может быть ценен. Другими копипастами из LLM? Потому что, повторюсь, статья, при ее технической корректности, Вашу экспертность скорее антиутверждает

Обычный Enum — штука классная, но строгая. Если ты создашь OrderStatus.PENDING = 1, а потом попробуешь сравнить его просто с числом (if status == 1), Python скажет: «Э, нет, это разные вещи!». Для него объект перечисления не равен числу, даже если внутри него спрятана единица.

Но в реальности мы часто получаем данные из баз данных или через API в виде обычных чисел. И тут на сцену выходит IntEnum.

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

Жалко, что в питоне нету встроенной поддержки enum на уровне синтаксиса, как в C++, к примеру. А то так выходит много абстракций и всё-таки это чуть более громоздко.

Код на «магических строках»

Погодите, так реально что ли пишут на питоне? И там что, нет поддержки enum из коробки, что вот это всё надо городить? Или это какой-то галюциногенный угар от чатжпт?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации