Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs
На предыдущем
занятии мы с вами познакомились с общим классом Enum для создания
перечислений в Python-программах. Однако часто на практике
требуются специализированные перечисления, состоящие только из набора целых
чисел или строк. Для их определения доступны следующие два класса:
- IntEnum – для создания
перечисления из набора целых чисел;
- StrEnum – для создания
перечисления из набора строк.
Давайте
посмотрим, чем эти классы отличаются от ранее рассмотренного класса Enum. Предположим,
что нам нужно сформировать перечисление для дней недели. Сделаем это следующим
образом:
import enum
class Week(enum.IntEnum):
Monday = 1
Tuesday = 2
Wednesday = 3
Thursday = 4
Friday = 5
Saturday = 6
Sunday = 7
С элементами
такого перечисления возможны следующие операции:
p1 = Week.Monday
p2 = Week.Friday
p1 == Week.Monday # True
p1 == 1 # True
p1 == Week.Thursday # False
p1 == p2 # False
p1.value # 1
p2.name # 'Friday'
p1 + p2 # 6
p1 < p2 # True
p2 <= p1 # False
Обратите
внимание, объекты p1, p2 можно сравнивать на равенство не
только с объектами Week.Monday, Week.Thursday, но и с
конкретными числами. Кроме того, с p1, p2 можно
выполнять различные арифметические операции, как с целыми числами, что было
недопустимо с объектами обычного перечисления Enum. Кроме того,
если попытаться присвоить какому-либо атрибуту значение, не приводящееся к
целочисленному, например:
class Week(enum.IntEnum):
Monday = 'a'
...
то при выполнении
программы возникнет ошибка ValueError. То есть, класс IntEnum гарантирует
целочисленные значения своих элементов и расширяет их операции до сравнения с
числами и различных арифметических действий.
Пример использования перечисления IntEnum
Рассмотрим
небольшой пример использования данного перечисления. Объявим функцию, которая
будет выдавать список предметов для указанного дня:
def get_subjects(day: Week):
match day:
case Week.Monday:
return "Информатика", "Математика"
case Week.Tuesday:
return "Физика",
case Week.Friday:
return "Машинное обучение", "Математика", "Информатика"
case _:
return tuple()
Здесь
используется конструкция match/case для выбора
указанного дня и если шаблон проверки совпадает, то возвращается кортеж из
названий дисциплин. Последний case реализует поведение по умолчанию,
возвращающий пустой кортеж.
Воспользоваться
этой функцией можно следующим образом:
subjects = get_subjects(Week.Friday)
print(subjects)
После запуска
программы, получим:
('Машинное
обучение', 'Математика', 'Информатика')
Обратите
внимание, что из-за использования типа IntEnum, мы можем в
аргументе указать целое число, соответствующее дню Friday:
subjects = get_subjects(5)
Результат будет
тем же.
Перечисления типа StrEnum
По аналогии
работает перечисление типа StrEnum, которое в качестве значений
атрибутов требует строковые данные. Например:
class Filter(enum.StrEnum):
ASC = 'ascend'
DESC = 'descent'
BYID = 'id'
Который можно
также перебрать с помощью цикла for:
for p in Filter:
print(f"{p.name}: {p.value}")
Или, извлечь
любое значение по имени атрибута:
p1 = Filter.DESC # <enum 'Filter'>
p2 = Filter['ASC'] # <enum 'Filter'>
Каждый элемент
будет являться объектом класса Filter. С этими элементами допустимы
следующие операции:
p1 == p2 # False
p2 == Filter.ASC # True
p1 < Filter.BYID # True (лексикографическое сравнение строк)
p2 >= Filter.DESC # False
p1 + p2 # 'descentascend'
То есть, можно
выполнять те же операции, что и со строками.
Если при
объявлении перечисления типа StrEnum в значении какого-либо атрибута
указать не строковую величину, например:
class Filter(enum.StrEnum):
ASC = 'ascend'
DESC = 'descent'
BYID = 'id'
p1 = ('1', '2') # ошибка (кортеж)
p2 = 5 # ошибка (число)
то возникнет
ошибка TypeError. Здесь следует явно прописывать строки или строковые
переменные.
Вот так классы перечислений
Enum, IntEnum, StrEnum позволяют
структурировать данные, делая код понятнее и надежнее. Их использование повышает
качество программного продукта благодаря строгому контролю над допустимым
набором значений. Поэтому, если в проекте требуется ограничение списка
возможных состояний, то для этого очень хорошо подходят классы перечислений.
Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs