enum

Wyliczenia: zestaw nazwanych stałych, np. poziomów trudności albo statusów zadania, zamiast luźnych napisów i liczb.

Na tej stronie

Przykład

#
Python
from enum import Enum

class Difficulty(Enum):
    EASY = 1
    MEDIUM = 2
    HARD = 3

level = Difficulty.HARD
print(level)
print(level.name, level.value)
print(level is Difficulty.HARD)
print(Difficulty(2).name, Difficulty["EASY"].value)
print([d.name for d in Difficulty])
Wynikzapisany wynik, możesz go sprawdzić
Difficulty.HARD
HARD 3
True
MEDIUM 1
['EASY', 'MEDIUM', 'HARD']

Definicja i zastosowanie

#

Moduł enum pozwala zdefiniować wyliczenie, czyli klasę z zamkniętą listą nazwanych wartości. Zamiast wpisywać w kodzie napisy "easy" i "hard", w których łatwo o literówkę, tworzysz klasę Difficulty(Enum) z członkami EASY, MEDIUM i HARD. Każdy członek ma nazwę (.name) i wartość (.value).

Członków porównuje się przez is albo ==, a literówka w nazwie, np. Difficulty.EASSY, od razu zgłasza AttributeError. Po wyliczeniu można iterować w kolejności definicji, a członka odczytasz po wartości (Difficulty(2)) albo po nazwie (Difficulty["HARD"]). Wartości nie muszą być liczbami, a funkcja auto() nada je automatycznie.

Zwykły członek Enum nie jest równy swojej wartości: Difficulty.EASY == 1 to False. Gdy członkowie mają zachowywać się jak napisy albo liczby, np. przy zapisie do JSON czy porównaniu z danymi z bazy, użyj StrEnum albo IntEnum. Wyliczenia dobrze współpracują z instrukcją match, w której członka podaje się z kropką: case Difficulty.HARD:.

Składnia

#
Składnia
from enum import Enum, auto

class Nazwa(Enum):
    CZLONEK = wartosc
    INNY = auto()

Nazwa.CZLONEK.name
Nazwa.CZLONEK.value
Nazwa(wartosc)
Nazwa["CZLONEK"]

Najważniejsze elementy

#
  • Enum

    Podstawowe wyliczenie. Członkowie są równi tylko samym sobie, a nie swoim wartościom.
  • StrEnum

    Członkowie są napisami: równają się swoim wartościom i trafiają do f-stringów jako sama wartość. Od Pythona 3.11.
  • IntEnum

    Członkowie są liczbami całkowitymi, więc można ich porównywać z liczbami i używać w obliczeniach.
  • Flag

    Wartości można łączyć operatorem | i sprawdzać przez in, np. zestaw uprawnień.
  • auto()

    Nadaje wartości automatycznie: w Enum kolejne liczby od 1, a w StrEnum nazwę członka zapisaną małymi literami.

Więcej przykładów

#
StrEnum i auto()
Python
from enum import StrEnum, auto

class Status(StrEnum):
    TODO = auto()
    IN_PROGRESS = auto()
    DONE = auto()

task = {"number": "7_3", "status": Status.DONE}

print(Status.IN_PROGRESS.value)
print(task["status"] == "done")
print(f"Status: {task['status']}")
print(Status("todo").name)
Wynikzapisany wynik, możesz go sprawdzić
in_progress
True
Status: done
TODO
Metody wyliczenia i match
Python
from enum import Enum

class Difficulty(Enum):
    EASY = 1
    MEDIUM = 2
    HARD = 3

    @property
    def exp(self):
        return self.value * 10

def label(difficulty):
    match difficulty:
        case Difficulty.EASY:
            return "Na rozgrzewkę"
        case Difficulty.HARD:
            return "Dla wytrwałych"
        case _:
            return "Standard"

for d in Difficulty:
    print(d.name, d.exp, label(d))
print(Difficulty.EASY == 1)
Wynikzapisany wynik, możesz go sprawdzić
EASY 10 Na rozgrzewkę
MEDIUM 20 Standard
HARD 30 Dla wytrwałych
False
Flag: łączenie uprawnień
Python
from enum import Flag, auto

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

mentor = Permission.READ | Permission.WRITE
print(Permission.WRITE in mentor, Permission.DELETE in mentor)
print([p.name for p in mentor])
print(mentor.value)
Wynikzapisany wynik, możesz go sprawdzić
True False
['READ', 'WRITE']
3

Dobre praktyki

#
  • Porównuj członków z innymi członkami, a nie z napisami czy liczbami. Do porównań z surowymi wartościami służą StrEnum i IntEnum.
  • Nazwy członków pisz wielkimi literami, jak stałe: Status.DONE.
  • Do zapisu w JSON używaj .value, a przy odczycie zamieniaj wartość z powrotem na członka przez Status(wartosc).

Powiązane hasła

#

Widzisz błąd albo brakuje przykładu? Napisz do nas.