Плохая практика - использовать перечисления с нецелочисленными типами в Python?

Предположим, у меня есть класс, расширяющий Enum, с именем foo; Однако вместо использования целых чисел для каждого элемента я использую строки

from enum import Enum
class foo (Enum):
    foo = "Hello"
    bar = ", "
    foobar = "world"
    barfoo = "!"

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

from enum import Enum
class foo (Enum):
    foo = {"text" : "Hello", "meaning" : "hello"}
    bar = {"text" : ", ", "meaning" : "comma"}
    foobar = {"text" : "world", "meaning" : "world"}
    barfoo = {"text" : "!", "meaning" : "exclamation"}

Ну, лабиринт, почему бы тогда просто не использовать обычный класс? Что ж, очень полезно иметь возможность хранить эту информацию в виде перечисления для быстрого сравнения типов. Например, x = {"name" : "foo", "type" : foo.foo} можно легко проверить на тип с помощью if x[type] is foo.foo.

Это «плохая практика»? Под этим я имею в виду:

  1. Это предполагаемое использование Enum?
  2. Если бы я вынул (Enum) из class foo (Enum):, будет ли разница в эффективности при сравнении?
  3. Есть ли лучший способ сделать то, что я хочу делать?

Я бы опасался изменять значения.

juanpa.arrivillaga 07.07.2018 20:56
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
1
802
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  • Плохая практика - использовать перечисления с нецелочисленными типами в Python?

Нет, это неплохая практика.

  • Это предполагаемое использование Enum

Да, Enum был разработан для работы с нецелочисленными типами.

  • Если бы я вынул (Enum) из класса foo (Enum):, будет ли разница в эффективности при сравнении?

Версия без Enum, вероятно, будет быстрее, но это, вероятно, не имеет значения. (Проверьте узкие места, прежде чем угадывать, что нужно оптимизировать.)

  • Есть ли лучший способ сделать то, что я хочу делать?

Использование изменяемых типов разрешено - это означает, что я не предпринял никаких шагов, чтобы запретить это 1, - но, как правило, это не очень хорошая идея. Члены Enum должны быть постоянными. Ваш пример выглядит так, как будто вы хотите иметь два дополнительных атрибута для каждого члена: text и meaning - это возможно как в версии Enum stdlib, так и в версии Advanced EnumerationEnum:

from aenum import AutoNumberEnum

class Foo(AutoNumberEnum):
    _init_ = 'text meaning'
    foo = "Hello", "hello"
    bar = ", ", "comma"
    foobar = "world", "world"
    barfoo = "!", "exclamation"

и в использовании:

>>> Foo.bar
<Foo.bar: 2>

>>> Foo.bar.text
', '

>>> Foo.bar.meaning
'comma'

См. этот ответ, чтобы узнать, как это сделать с помощью stdlib.


1 Раскрытие: я являюсь автором библиотек Python stdlib Enum, enum34 задний порт и Расширенное перечисление (aenum).

Этот парень enums

AetherUnbound 07.07.2018 21:34

Ого, AutoNumberEnum в значительной степени именно то, что я хочу. Спасибо!

MazeOfEncryption 07.07.2018 21:44

Другие вопросы по теме