У багатьох мовах програмування, як-от C, C++ і Java, переліки (enum) є популярним типом даних. Вони допомагають створювати безпечний та зрозумілий код.
В Python підтримка переліків з’явилася не одразу. Але, починаючи з версії 3.4, Python офіційно підтримує переліки. Ця стаття є вичерпним керівництвом про те, як створювати переліки, використовувати їх та як вони покращують читабельність вашого коду.
Що таке Enum і яка його роль?
Enum (enumeration), або перелік, – це тип даних, визначений набором можливих значень. Цей набір значень називається множиною його членів. Переліки дозволяють точно визначити, які значення може мати змінна, що сприяє написанню безпечного коду та покращує його читабельність.
Основні поняття
Розглядаючи переліки, необхідно спочатку визначити деякі ключові терміни, які ми будемо часто використовувати: члени та значення.
- Члени: це іменовані константи, які складають набір значень, що належать до переліку. Наприклад, перелік “Дні тижня” може містити такі члени, як “Понеділок”, “Вівторок” тощо.
- Значення: це внутрішні значення, які чітко представляють кожного члена переліку. Вони дозволяють виконувати порівняння. Наприклад, у переліку “Дні тижня” “Понеділок” може мати значення 1, “Вівторок” – 2, і так далі.
Тепер обговоримо, яким чином Enum покращує код.
Як переліки роблять код кращим?
Переліки покращують ваш код, роблячи його більш читабельним і менш схильним до помилок. Ось кілька причин, чому варто їх використовувати:
- Переліки дозволяють чітко визначити, які значення очікуються від змінної чи аргументу функції. Це робить код легшим для розуміння іншими розробниками.
- Enum робить ваш код самодокументованим. Вам не потрібно додавати коментарі, щоб описати, які значення очікує функція – перелік сам по собі визначає ці очікування.
- Інтегровані середовища розробки (IDE) можуть виявляти помилки, коли ви передаєте некоректні значення, а також надавати підказки для автодоповнення коду.
- В результаті ваш код стає безпечним з точки зору типів даних і менш схильним до виникнення помилок під час виконання.
Далі ми розглянемо способи створення переліків у Python.
Як створити Enum у Python?
Python не має вбудованої підтримки для переліків безпосередньо. Проте, у стандартній бібліотеці є модуль `enums`, який ми будемо використовувати в цьому посібнику. Існує два способи створення переліків у Python: за допомогою класів або функціонального API. Ми розглянемо обидва методи.
Необхідні умови
Щоб слідувати цьому посібнику, вам потрібен Python версії 3.4 або новішої. Ця версія включає модуль `enum` у стандартну бібліотеку. Якщо у вас немає потрібної версії, ось посібник, який допоможе з встановленням:
Для розуміння матеріалу вам потрібні базові знання Python, а також більш продвинуті концепції об’єктно-орієнтованого програмування, такі як класи та успадкування.
#1. Метод класу
Перший спосіб створення переліків — використовувати класи. Спочатку потрібно імпортувати клас `Enum` з модуля `enum`. Потім створити перелік, оголосивши клас, який успадкує клас `Enum`.
from enum import Enum class Direction(Enum): NORTH = 0 EAST = 1 SOUTH = 2 WEST = 3
Ви можете присвоювати членам переліку довільні значення. Наприклад, замість 0, 1, 2 і 3 для нашого переліку напрямків, ми можемо використовувати значення кутів: 0, 90, 180 та 270.
from enum import Enum class Direction(Enum): NORTH = 0 EAST = 90 SOUTH = 180 WEST = 270
Для більш лаконічного присвоєння значень можна скористатися функцією `range`. Ось як це можна зробити:
from enum import Enum class Direction(Enum): NORTH, EAST, SOUTH, WEST = range(0, 360, 90)
Тут ми генеруємо значення за допомогою функції `range`, починаючи з 0, закінчуючи 360 (не включно), зі збільшенням на 90. Потім ми розпаковуємо ці значення, подібно до того, як розпаковуємо кортежі. Якщо вас цікавить детальніше інформація про кортежі, прочитайте нашу статтю про кортежі у Python.
Класи Enum є абстрактними, тобто не призначені для створення екземплярів. Замість цього ми отримуємо доступ до їх властивостей, які представляють члени переліку, напряму.
#2. Метод функції
Метод функції є альтернативою методу підкласу.
from enum import Enum Direction = Enum("Direction", ["NORTH", "EAST", "SOUTH", "WEST"])
У цьому коді ми створили перелік під назвою `Direction` з чотирма членами. За замовчуванням ці члени отримують значення, починаючи з 1. Таким чином, `NORTH` дорівнює 1, `EAST` дорівнює 2, і так далі. Нумерація починається з 1, а не з 0, щоб всі значення були “істинними”, оскільки 0 вважається “хибним”.
Можна також присвоювати значення членам, передаючи їх як список кортежів. Кожен кортеж містить два елементи: ім’я члена та його значення.
from enum import Enum Direction = Enum( name = "Direction", values = [ ("NORTH", "n"), ("EAST", "e"), ("SOUTH", "s"), ("WEST", "w"), ] )
У цьому прикладі ми використовували рядки замість цілих чисел для присвоєння значень. Це показує, що рядки є так само дійсними значеннями, як і цілі числа.
Як використовувати Enum?
У попередньому розділі ми обговорили створення переліків та присвоєння значень членам. У цьому розділі ми розглянемо, як використовувати переліки для доступу до членів, присвоєння значень і перевірки на рівність.
Як отримати доступ до членів?
Існує кілька способів отримати доступ до членів переліку: синтаксис крапки, круглі дужки та квадратні дужки. Ось приклад:
from enum import Enum # Створення enum class Day(Enum): SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY = range(1, 8) # Доступ до членів enum # 1. Використання синтаксису крапки print(Day.SUNDAY) # 2. Використання квадратних дужок print(Day["MONDAY"]) # 3. Використання круглих дужок print(Day(3))
Після отримання доступу до члена enum, його можна зберегти у змінній. Важливо зазначити, що доступ до члена повертає посилання на об’єкт-член, а не його значення чи назву.
Доступ до імені та значення
Як вже згадувалось, доступ до члена enum створює посилання на об’єкт-член. Якщо потрібно отримати доступ до назви або значення об’єкта enum, використовуйте властивості `name` і `value` відповідно.
print(Day.SUNDAY.name, Day.SUNDAY.value)
Перевірка на рівність
Пам’ятайте, що присвоєння члена переліку змінній створює посилання на об’єкт-член. Тому для перевірки, чи має змінна певний член enum, використовуйте оператор `is`, щоб перевірити, чи член enum і змінна вказують на той самий об’єкт.
Приклад:
today = Day.WEDNESDAY if today is Day.MONDAY: print("Сьогодні понеділок, :(") if today is Day.WEDNESDAY: print("Щасливої середи")
Також можна використовувати оператор `==`. У суперкласах класу `Enum` оператор `==` є обгорткою для оператора `is`, що реалізовано за допомогою перевантаження оператора. Ви можете прочитати про це детальніше у нашій статті про магічні методи. Нижче наведений приклад з використанням `==` замість `is`:
today = Day.WEDNESDAY if today == Day.MONDAY: print("Сьогодні понеділок, :(") if today == Day.WEDNESDAY: print("Щасливої середи")
Важливо повторити, що порівняння enum перевіряє ідентичність об’єктів, а не значення.
Заключні слова
У цій статті ми розглянули, що таке переліки, і чому вони є корисними. Ми також вивчили різні методи створення переліків, використовуючи підклас класу `Enum` та функціональний API.
Крім того, ми розглянули, як використовувати переліки, отримувати доступ до значень і виконувати порівняння. Далі ви можете прочитати нашу статтю про переліки у TypeScript.