Какое преимущество дает использование Enum, когда оно не кодирует базовые значения? - PullRequest
0 голосов
/ 10 мая 2018

Я понимаю смысл использования Enum, когда он преобразует удобочитаемую строку в базовое (например, числовое) значение, с классом FederalHoliday в этот ответ является хорошим примером тот.

Но вариант использования, который я рассматриваю, это то, где параметр функции ограничен набором возможных значений, которые в настоящее время передаются как "магические строки". Таким образом, реализация Enum здесь действительно не улучшит читабельность кода (во всяком случае, это сделает код более загруженным). И превращение строки в Enum только для сравнения того, что фактически является одной и той же строкой (то есть именем Enum), выглядит излишним.

Этот ответ имеет фантастический список общих преимуществ перечислений, но я не уверен, сколько из них применимо в этом случае.

Чтобы прояснить тот случай, который я имею в виду, здесь есть пример этого с функцией, которая печатает строку с определенной заглавной буквой, как указано mode:

def print_my_string(my_string, mode):
    if mode == 'l':
        print(my_string.lower())
    elif mode == 'u':
        print(my_string.upper())
    elif mode == 'c':
        print(my_string.capitalize())
    else:
        raise ValueError("Unrecognised mode")

Чтобы увидеть это в действии, запустите:

for mode in ['l', 'u', 'c']:
    print_my_string("RaNdoM CAse StRING", mode)

дает:

random case string
RANDOM CASE STRING
Random case string

Итак, мой вопрос:

Какое преимущество дает Enum, когда строки не представляют другое значение внизу? Есть ли способ сделать код более надежным? добавляет что-нибудь?


Другие вещи, которые я читал:

В основном около Enum с, особенно когда строки представляют другое значение под:

Этот пример похож на мой (под Перечисления могут взаимодействовать ), но я изо всех сил пытался понять техническую дискуссию вокруг него, и он показывает только настройку Enum, а не ее использование:

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Вы правы в том, что, не будучи языком со статической типизацией, преимущества перечислений не так сильны в Python.Многие API по-прежнему используют строки для подобных вещей, и это нормально.Однако я думаю, что у него все еще есть преимущества, особенно с точки зрения поддержки IDE (автозаполнение) и статического анализа (кодирование кода).Представьте, что у вас есть функция, которая позволяет вам вычислять норму вектора, используя разные методы.Были варианты 'Euclidean', 'Absolute' и 'Manhattan', 'EUCLIDEAN', 'ABSOLUTE_VALUE' и 'TAXICAB' или просто 'e', 'a' и 'm'?Если у вас есть enum и достаточно хорошая IDE, вы, вероятно, можете написать NormType. и нажать Ctrl + Пробел , чтобы увидеть варианты, вместо того, чтобы снова проверять документацию,И если вы напишите не то, что кодовый линтер, вероятно, сообщит вам.Более того, если вам случится переименовать один из вариантов, вам будет легче найти все места, которые нужно изменить.

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

0 голосов
/ 10 мая 2018

Что ж, ясность кода, вероятно, зависит от личности и стилей, но enum делает это понятнее, подумайте, что если вам нужно изменить строку, которую вы хотите использовать в качестве флага, вам придется реорганизовать весь ваш код при использовании и перечислить вас просто нужно изменить его в классе enum. Для меня имеет смысл использовать enum:

from enum import Enum

class PrintFlag(Enum):
  L = "lower"
  U = "upper"
  C = "capitalize"

def print_my_string(my_string, mode):
    action_dict = {
      PrintFlag.L : str.lower,
      PrintFlag.U : str.upper,
      PrintFlag.C : str.capitalize,
    }
    try:
      print(action_dict[mode](my_string))
    except KeyError:
      raise ValueError("Unrecognised mode")


for mode in PrintFlag:
    print_my_string("RaNdoM CAse StRING", mode)

Здесь у вас есть живой пример

...