Перечисления enum в Python

В данное руководство рассказывается, как работать с перечислениями (enum) в Python. Перечисление — это новый тип данных, введенный в Python 3.4.

Enum в Python

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

Модуль enum используется для создания перечислений в Python. Вы можете определить их с помощью ключевого слова class или с помощью функционального API.

Существуют специальные производные перечисления enum.IntEnum, enum.IntFlag и enum.Flag.

Простой пример использования enum в Python

Ниже приведен простой пример кода на Python, использующего перечисления.

    #!/usr/bin/python3
    
    from enum import Enum
     
    class Weapon(Enum):
        SWORD = 1
        BOW = 2
        DAGGER = 3
        CLUB = 4
    
    ranged_weapon = Weapon.BOW
    print(ranged_weapon)
    
    if ranged_weapon == Weapon.BOW:
        print("It's a bow")
    
    print(list(Weapon))

В примере у нас есть перечисление Weapon, которое имеет четыре различных значения: SWORD, BOW, DAGGER и CLUB. Чтобы получить доступ к одному из членов enum, мы должны указать название перечисления, за которым следует точка и имя интересующей нас символической константы.

    class Weapon(Enum):
        SWORD = 1
        BOW = 2
        DAGGER = 3
        CLUB = 4

Перечисление Weapon создается нами с помощью ключевого слова class, то есть происходит наследование от базового класса enum.Enum. После этого мы явно задаем числа, соответствующие значениям перечисления.

    ranged_weapon = Weapon.BOW
    print(ranged_weapon)

Здесь символическая константа присваивается переменной и выводится на консоль.

    if ranged_weapon == Weapon.BOW:
        print("It's a bow")

Данный фрагмент демонстрирует использование Weapon.BOW в выражении if.

С помощью встроенной функции list мы получаем список всех возможных значений для перечисления Weapon.

Вывод:

Еще один пример использования enum в Python

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

    #!/usr/bin/python3
    
    from enum import Enum
    
    class Weapon(Enum):
            SWORD = 1
            BOW = 2
            DAGGER = 3
            CLUB = 4
    
    weapon = Weapon.SWORD
    
    print(weapon)
    print(isinstance(weapon, Weapon))
    print(type(weapon))
    print(repr(weapon))
    
    print(Weapon['SWORD'])
    print(Weapon(1))

И снова мы имеем дело с enum Weapon, созданным с помощью класса.

Здесь мы выводим человекочитаемое строковое представление одного из членов перечисления.

С помощью метода isinstance мы проверяем, имеет ли переменная значение типа Weapon.

Функция type выводит тип переменной.

Функция repr предоставляет дополнительную информацию о перечислении.

Доступ к символической константе можно получить как по ее имени, так и по значению (индексу).

Вывод:

Функциональное создание enum в Python

Перечисления Python также могут быть созданы с помощью функционального API.

    from enum import Enum
    
    Weapon = Enum('Weapon', 'SWORD BOW DAGGER CLUB', start=1)
    
    weapon = Weapon.DAGGER
    print(weapon)
    
    if weapon == Weapon.DAGGER:
        print("Dagger")

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

Weapon = Enum('Weapon', 'SWORD BOW DAGGER CLUB', start=1)

Здесь наименования символических констант задаются в строке, разделенные пробелами. Число, переданное в start, определяет начало нумерации значений для членов перечисления.

Вывод:

Итерирование enum в Python

Мы можем выполнять итерацию по перечислениям Python.

    from enum import Enum

    Weapon = Enum('Weapon', 'SWORD BOW DAGGER CLUB', start=10)

    for weapon in Weapon:
        print(weapon)

    for weapon in Weapon:
        print(weapon.name, weapon.value)

В этом примере мы создаем перечисление Weapon, где символьные константы задаются в виде списка строк.

В коде выше мы выполняем итерации по членам перечисления в цикле for.

    for weapon in Weapon:
        print(weapon.name, weapon.value)

Здесь мы выводим их имена и значения.

Вывод:

Weapon.SWORD
Weapon.BOW
Weapon.DAGGER
Weapon.CLUB
SWORD 10
BOW 11
DAGGER 12
CLUB 13

Автоматическое назначение имен для enum в Python

Значения символьных констант могут быть автоматически установлены с помощью функции auto().

    #!/usr/bin/python3
    
    from enum import Enum, auto
    
    class Weapon(Enum):
        SWORD = auto()
        BOW = auto()
        DAGGER = auto()
        CLUB = auto()
    
    for weapon in Weapon:
        print(weapon.value)

В этом фрагменте мы создали перечисление Weapon, члены которого получают значения с помощью функции auto.

Вывод:

Уникальные значения enum в Python

Значения символьных констант могут быть принудительно уникальными с помощью декоратора @unique.

#!/usr/bin/python3

from enum import Enum, unique

@unique
class Weapon(Enum):
    SWORD = 1
    BOW = 2
    DAGGER = 3
    CLUB = 3
    # CLUB = 4

for weapon in Weapon:
    print(weapon)

Данный пример завершается с ошибкой ValueError: duplicate values found in : CLUB -> DAGGER, потому что члены CLUB и DAGGER имеют одинаковые значения. Если мы закомментируем декоратор @unique, пример выведет три члена; CLUB игнорируется.

Python enum __members__

Специальный атрибут members представляет собой упорядоченное отображение имен на символьные константы enum, доступное только для чтения.

#!/usr/bin/python3

from enum import Enum

Weapon = Enum('Weapon', [('SWORD', 1), ('BOW', 2), 
    ('DAGGER', 3), ('CLUB', 4)])

for name, member in Weapon.__members__.items():
    print(name, member)

В этом примере мы используем свойство members. Члены перечисления заданы списком кортежей с помощью функционального API.

Вывод:

    SWORD Weapon.SWORD
    BOW Weapon.BOW
    DAGGER Weapon.DAGGER
    CLUB Weapon.CLUB

enum.Flag

Enum.Flag — это базовый класс для создания пронумерованных констант, которые можно объединять с помощью побитовых операций без потери их принадлежности к Flag.

#!/usr/bin/python3

from enum import Flag, auto

class Permission(Flag):
    READ = auto()
    WRITE = auto()
    EXECUTE = auto()

print(list(Permission))
print(Permission.READ | Permission.WRITE)

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

Вывод:

    [<Permission.READ: 1>, <Permission.WRITE: 2>, <Permission.EXECUTE: 4>]
    Permission.WRITE|READ
Максим
Я создал этот блог в 2018 году, чтобы распространять полезные учебные материалы, документации и уроки на русском. На сайте опубликовано множество статей по основам python и библиотекам, уроков для начинающих и примеров написания программ.
Мои контакты: Почта
admin@pythonru.comAlex Zabrodin2018-10-26OnlinePython, Programming, HTML, CSS, JavaScript