enum
Wyliczenia: zestaw nazwanych stałych, np. poziomów trudności albo statusów zadania, zamiast luźnych napisów i liczb.
Przykład
#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])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
#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ć przezin, np. zestaw uprawnień.auto()
Nadaje wartości automatycznie: wEnumkolejne liczby od 1, a wStrEnumnazwę członka zapisaną małymi literami.
Więcej przykładów
#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)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)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)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żą
StrEnumiIntEnum. - 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 przezStatus(wartosc).
Powiązane hasła
#- classDefiniuje klasę: szablon obiektów łączący dane i funkcje, które na nich działają.
- match, caseDopasowanie wzorców: wybór gałęzi kodu na podstawie wartości i kształtu danych.
- @dataclassDekorator, który na podstawie pól z adnotacjami typów generuje __init__, __repr__ i __eq__ klasy przechowującej dane.
- typingAdnotacje typów: opis, jakich wartości oczekuje funkcja i co zwraca. Sprawdzają je edytory i narzędzia takie jak mypy.
- jsonZamienia dane Pythona na tekst JSON i z powrotem. Podstawa zapisu danych i komunikacji z API.
Widzisz błąd albo brakuje przykładu? Napisz do nas.