Last modified: June 06, 2026
This article is written in: 🇵🇱
Enum (od angielskiego słowa "enumerate" - numerować) to specjalny typ danych w Pythonie, który pozwala na definiowanie uporządkowanych zestawów nazwanych wartości. Wartości te są unikalne i niemodyfikowalne, co czyni je idealnymi do reprezentowania stałych w kodzie.
Główną zaletą używania Enum jest czytelność i bezpieczeństwo kodu. Dzięki nim możemy zastąpić "magiczne" wartości liczbowe czy tekstowe bardziej opisowymi nazwami, co zwiększa zrozumiałość kodu.
Enum są bardziej zrozumiałe i opisowe, co zdecydowanie zwiększa czytelność kodu w porównaniu do używania "magicznych" liczb lub ciągów znaków.Enum zapewnia bezpieczeństwo typów, ponieważ pozwala na użycie tylko wcześniej określonych wartości, co zmniejsza ryzyko błędów.Enum są niemodyfikowalne, co oznacza, że po ich zdefiniowaniu nie można ich zmienić, co dodatkowo zwiększa stabilność kodu.Enum powiązane wartości mogą być łatwo zorganizowane w jednym miejscu, co wpływa na lepszą organizację kodu.Aby korzystać z Enum, należy najpierw zaimportować odpowiedni moduł.
from enum import Enum, auto
Definicja klasy Enum polega na tworzeniu atrybutów klasy, które reprezentują stałe symboliczne. Każdy atrybut w klasie Enum jest jednym z jego członków i ma unikalną wartość. Możemy jawnie przypisać wartość do członka lub użyć enum.auto(), aby automatycznie przypisać kolejną dostępną wartość.
Przykład definicji Enum dla kolorów:
from enum import Enum, auto
class Kolor(Enum):
ZIELONY = auto()
CZERWONY = auto()
NIEBIESKI = auto()
kolor_a = Kolor.ZIELONY
kolor_b = Kolor.CZERWONY
print(kolor_a.name) # ZIELONY
print(kolor_a.value) # 1
print(kolor_b.name) # CZERWONY
print(kolor_b.value) # 2
Możemy również przypisać jawne wartości do członków Enum, co może być przydatne, gdy wartości te mają specjalne znaczenie lub muszą być zgodne z zewnętrznymi systemami.
from enum import Enum
class Status(Enum):
AKTYWNY = 1
NIEAKTYWNY = 0
ZAWIESZONY = -1
status = Status.AKTYWNY
print(status.name) # AKTYWNY
print(status.value) # 1
Pola Enum mogą być porównywane tylko z innymi członkami tego samego Enum. Porównywanie pól różnych Enum lub porównywanie pól z wartościami liczbowymi/textowymi spowoduje błąd.
if kolor_a == Kolor.ZIELONY:
print("Kolor jest zielony!")
# Poniższe porównanie spowoduje błąd:
# if kolor_a == 1:
# print("Błąd!")
Możemy łatwo iterować po wszystkich członkach Enum za pomocą pętli.
for kolor in Kolor:
print(kolor)
Wynik:
Kolor.ZIELONY
Kolor.CZERWONY
Kolor.NIEBIESKI
Enum są szczególnie przydatne w sytuacjach, gdy mamy do czynienia z zestawem stałych wartości, które mogą być przypisane do zmiennych, takich jak stany aplikacji, kategorie produktów, role użytkowników itp. Dzięki Enum kod staje się bardziej zrozumiały i mniej podatny na błędy.
from enum import Enum, auto
class Ranga(Enum):
POCZATKUJACY = auto()
SREDNIOZAAWANSOWANY = auto()
ZAAWANSOWANY = auto()
def okresl_rangę(uzytkownik):
if uzytkownik.punkty < 100:
return Ranga.POCZATKUJACY
elif uzytkownik.punkty < 1000:
return Ranga.SREDNIOZAAWANSOWANY
else:
return Ranga.ZAAWANSOWANY
# Przykładowe użycie:
class Uzytkownik:
def __init__(self, imie, punkty):
self.imie = imie
self.punkty = punkty
uzytkownik = Uzytkownik("Anna", 150)
ranga = okresl_rangę(uzytkownik)
print(f"Użytkownik {uzytkownik.imie} ma rangę: {ranga.name}")
Wynik:
Użytkownik Anna ma rangę: SREDNIOZAAWANSOWANY
Możemy konwertować wartości na Enum i z powrotem:
from enum import Enum
class Status(Enum):
AKTYWNY = 1
NIEAKTYWNY = 0
ZAWIESZONY = -1
# int → Enum
s = Status(1)
print(s) # Status.AKTYWNY
print(s.name) # AKTYWNY
print(s.value) # 1
# str → Enum (przez nazwę)
s2 = Status["ZAWIESZONY"]
print(s2) # Status.ZAWIESZONY
# Enum → int
print(s.value) # 1
print(int(s.value)) # 1
# Sprawdzenie przynależności
print(Status(0) in Status) # True
print(1 in [e.value for e in Status]) # True
IntEnum łączy cechy Enum z int: wartości mogą być bezpośrednio porównywane z liczbami:
from enum import IntEnum
class Priorytet(IntEnum):
NISKI = 1
SREDNI = 2
WYSOKI = 3
print(Priorytet.WYSOKI > Priorytet.NISKI) # True
print(Priorytet.SREDNI == 2) # True
print(Priorytet.WYSOKI + 1) # 4 (zwykła liczba int)
# Sortowanie z IntEnum
zadania = [
("raport", Priorytet.NISKI),
("aktualizacja", Priorytet.WYSOKI),
("backup", Priorytet.SREDNI),
]
posortowane = sorted(zadania, key=lambda x: x[1], reverse=True)
for nazwa, p in posortowane:
print(f"{nazwa}: {p.name}")
# aktualizacja: WYSOKI
# backup: SREDNI
# raport: NISKI
Flag (i IntFlag) służą do definiowania flag bitowych, które można łączyć operatorami bitowymi (|, &, ^, ~):
from enum import Flag, auto
class Uprawnienia(Flag):
ODCZYT = auto() # 1
ZAPIS = auto() # 2
WYKONANIE = auto() # 4
# Kombinowanie flag
uzytkownik = Uprawnienia.ODCZYT | Uprawnienia.ZAPIS
print(uzytkownik) # Uprawnienia.ODCZYT|ZAPIS
print(Uprawnienia.ODCZYT in uzytkownik) # True
print(Uprawnienia.WYKONANIE in uzytkownik) # False
# Dodawanie i usuwanie flag
uzytkownik |= Uprawnienia.WYKONANIE
print(Uprawnienia.WYKONANIE in uzytkownik) # True
uzytkownik &= ~Uprawnienia.ZAPIS
print(Uprawnienia.ZAPIS in uzytkownik) # False
Enum świetnie współpracuje z match:
from enum import Enum
class Kolor(Enum):
CZERWONY = 1
ZIELONY = 2
NIEBIESKI = 3
def opis_koloru(kolor):
match kolor:
case Kolor.CZERWONY:
return "Kolor czerwony — stop"
case Kolor.ZIELONY:
return "Kolor zielony — jedź"
case Kolor.NIEBIESKI:
return "Kolor niebieski — spokój"
print(opis_koloru(Kolor.ZIELONY)) # Kolor zielony — jedź
Domyślnie, jeśli dwa elementy Enum mają tę samą wartość, drugi staje się aliasem pierwszego:
from enum import Enum, unique
class Kierunek(Enum):
POLNOC = 1
N = 1 # alias — wskazuje na POLNOC
print(Kierunek.N is Kierunek.POLNOC) # True
print(list(Kierunek)) # [<Kierunek.POLNOC: 1>] — alias nie pojawia się w iteracji
Dekorator @unique wymusza, aby każda wartość była unikalna (błąd przy duplikatach):
from enum import Enum, unique
@unique
class Status(Enum):
AKTYWNY = 1
NIEAKTYWNY = 2
# ZAWIESZONY = 1 # ValueError: duplicate values found in <enum 'Status'>: ZAWIESZONY -> AKTYWNY
| Typ | Dziedziczy po | Porównanie z liczbą | Flagi bitowe | Zastosowanie |
Enum |
object |
Nie | Nie | Ogólny zestaw stałych |
IntEnum |
int, Enum |
Tak | Nie | Gdy potrzebujemy wartości liczbowej |
Flag |
Enum |
Nie | Tak | Flagi bitowe (czyste) |
IntFlag |
int, Flag |
Tak | Tak | Flagi bitowe + porównanie z int |
StrEnum |
str, Enum |
Tak (str) | Nie | Enum tekstowy (Python 3.11+) |