Какая обычная практика для перечислений в Python?

Возможный дубликат:
Как я могу представляют собой "перечисление" в Python?

Какая обычная практика для перечислений в Python? Т.е. как они воспроизводятся в Python?

public enum Materials
{
    Shaded,
    Shiny,
    Transparent,
    Matte
}

person Joan Venge    schedule 31.03.2009    source источник
comment
Теперь в Python 3.4 есть стандартный тип Enum. Прочтите это сообщение: stackoverflow.com/questions/ 16653129 /   -  person Javier    schedule 01.04.2014
comment
Вот PEP для типа перечисления, который сейчас присутствует в Python: python.org/dev / peps / pep-0435   -  person shuttle87    schedule 27.07.2015
comment
На закрытый вопрос лучший ответ :)   -  person Apollys supports Monica    schedule 07.12.2019


Ответы (4)


Я видел этот паттерн несколько раз:

>>> class Enumeration(object):
        def __init__(self, names):  # or *names, with no .split()
            for number, name in enumerate(names.split()):
                setattr(self, name, number)

>>> foo = Enumeration("bar baz quux")
>>> foo.quux
2

Вы также можете просто использовать члены класса, хотя вам придется указать свою собственную нумерацию:

>>> class Foo(object):
        bar  = 0
        baz  = 1
        quux = 2

>>> Foo.quux
2

Если вы ищете что-то более надежное (разреженные значения, исключение для конкретного перечисления и т. Д.), попробуйте это рецепт.

person Ben Blank    schedule 31.03.2009

Я понятия не имею, почему Enums изначально не поддерживает Python. Лучший способ, который я нашел для их эмуляции, - это переопределить _ str _ и _ eq _, чтобы вы могли их сравнивать, и когда вы используете print (), вы получаете строку вместо числового значения.

class enumSeason():
    Spring = 0
    Summer = 1
    Fall = 2
    Winter = 3
    def __init__(self, Type):
        self.value = Type
    def __str__(self):
        if self.value == enumSeason.Spring:
            return 'Spring'
        if self.value == enumSeason.Summer:
            return 'Summer'
        if self.value == enumSeason.Fall:
            return 'Fall'
        if self.value == enumSeason.Winter:
            return 'Winter'
    def __eq__(self,y):
       return self.value==y.value

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

>>> s = enumSeason(enumSeason.Spring)

>>> print(s)

Spring
person Spell    schedule 31.03.2009
comment
PEP354 имеет уведомление об отказе. См. python.org/dev/peps/pep-0354/#rejection -notice - person Fred Larson; 01.04.2009
comment
Было бы быстрее иметь словарь классов {Spring: 0, Summer: 1, ...} и использовать init для перебора записей и установки атрибутов, потому что тогда str можно было просто посмотреть значение, а не вручную кодировать для каждого случая. - person Charles J. Daniels; 29.03.2015
comment
См. Это: python.org/dev/peps/pep-0435 - person shuttle87; 27.07.2015

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

class AnimalEnum:
  @classmethod
  def verify(cls, other):
    return issubclass(other.__class__, cls)


class Dog(AnimalEnum):
  pass

def do_something(thing_that_should_be_an_enum):
  if not AnimalEnum.verify(thing_that_should_be_an_enum):
    raise OhGodWhy
person Trey Stout    schedule 31.03.2009

person    schedule
comment
Я такого раньше не видел, хорошие вещи. - person Ben Blank; 01.04.2009
comment
Единственная проблема в том, что мне нужно, чтобы первый элемент был 1. Можно ли это сделать с помощью вашего метода? - person Joan Venge; 01.04.2009
comment
Из всех методов, которые я видел, это, наверное, мой любимый. Очень элегантный! - person goldenratio; 01.04.2009
comment
@Joan Ты мог бы сделать _unused, Shaded, Shiny, Transparent, Matte = range(5) - person zekel; 09.12.2010
comment
Довольно поздно, но вы также можете сделать Shaded, Shiny, Transparent, Matte = range(1, 5), если вам не нравится, что _unused там - person Davy8; 30.01.2011
comment
Вам также не нужно использовать диапазон, присваивая каждой переменной класса значение индивидуально. - person bret; 14.06.2012
comment
К сожалению, этот метод создания перечисления является неполным, поскольку перечисления не могут быть повторены, а каждое значение не является уникальным типом (например, просто int). - person Gewthen; 10.06.2015
comment
@Gewthen Во многих языках перечисления - это просто int. Разве это не ожидается более или менее? При необходимости вы можете реализовать соответствующий итератор. - person Mads Y; 02.09.2015
comment
@MadsY В других языках это просто синтаксический сахар, а в других языках (например, Python3) - нет. Наличие сильного типа для ваших ценностей, как правило, лучше для языков со строгим типированием, потому что он больше использует язык. Если это просто числа, их следует помнить при отладке или просмотре журналов. Я бы предпочел просто увидеть Materials.shinny в журнале, чем 1, потому что 1 говорит мне гораздо меньше, чем Materials.shinny - person Gewthen; 17.10.2015
comment
Это должно быть обновлено, чтобы добавить, что enums находятся в Python с версии 3.4. - person SudoKid; 04.01.2017