Python Enum, StrEnum och Flag - så väljer du rätt

15 oktober 2026

En illustration som visar hur python enum fungerar, med komponenter för .name, .value, IntEnum, IntFlag och med en person som tittar på.

När en status i en webbapp kan vara "draft", "published" eller "archived" räcker en felstavad sträng för att skapa ett svårfunnet fel. En Enum ger statusen ett fast antal namngivna värden, men valet mellan vanlig Enum och dess sträng- eller heltalsvarianter beror på hur värdet ska användas utanför Python.

Kodexempel som visar hur man använder en python enum för att definiera ordertillstånd som PLACED, PROCESSING, SHIPPED, DELIVERED och RETURNED.

Välj enum-typ efter hur värdet ska användas

  • Enum passar när värdena ska vara tydligt avgränsade och inte bete sig som vanliga strängar eller tal.
  • StrEnum passar när värdena behöver fungera som strängar, exempelvis i JSON eller API-anrop.
  • IntEnum är främst till för kompatibilitet med äldre kod eller system som kräver heltal.
  • Flag används när flera alternativ kan kombineras, till exempel behörigheter.
  • Alias kan uppstå när två medlemmar får samma värde; dekoratören @unique stoppar det.

En Enum gör tillåtna statusar tydliga

En status som skickas runt som vanlig text kan råka få flera stavningar: "published", "Publish" eller "publised". Med en enum samlas de giltiga valen på ett ställe, och koden använder namngivna medlemmar i stället för lösa strängar.

from enum import Enum

class PageStatus(Enum):
    DRAFT = "draft"
    PUBLISHED = "published"
    ARCHIVED = "archived"

status = PageStatus.PUBLISHED

if status is PageStatus.PUBLISHED:
    print("Sidan visas")

Medlemmarna är egna enum-objekt. Därför är PageStatus.PUBLISHED inte samma sak som strängen "published"; använd status.value när själva värdet behövs. Jag tycker att vanlig Enum är det säkraste standardvalet när du vill att fel typ ska märkas tydligt.

StrEnum och IntEnum passar när kompatibilitet krävs

Problemet börjar ofta vid gränsen till ett API, en databas eller äldre kod. Om mottagaren kräver en vanlig sträng kan StrEnum låta enum-medlemmarna användas i många strängsammanhang, medan IntEnum gör medlemmarna kompatibla med heltal.

TypPassar närSe upp med
EnumDu vill ha avgränsade värden som inte likställs med vanliga strängar eller tal.Konvertera till .value där ett externt gränssnitt kräver råvärdet.
StrEnumEnum-värden ska användas som strängar.Vissa bibliotek kontrollerar exakt typ med type(x) == str; då kan str(member) behövas.
IntEnumÄldre kod eller ett externt system kräver numeriska konstanter.Medlemmarna kan jämföras med vanliga heltal, vilket gör typgränsen mindre strikt.

StrEnum lades till i Python 3.11. Enligt Python-dokumentationen för enum kan vissa funktioner kräva exakt typen str i stället för en underklass, så provkör serialisering och tredjepartsbibliotek innan du byter typ.

Värdena behöver inte vara unika om du tillåter alias

Två namn med samma värde är tillåtna i en enum, men det andra namnet blir då ett alias för det första. Därför är det missvisande att anta att varje rad i en enum automatiskt ger en separat medlem.

from enum import Enum, unique

@unique
class PageStatus(Enum):
    DRAFT = "draft"
    PUBLISHED = "published"
    LIVE = "published"  # ValueError

Här hindrar @unique att LIVE tyst blir ett extra namn för PUBLISHED. I Python-dokumentationens Enum HOWTO beskrivs även hur name och value skiljer sig: använd det första för medlemsnamnet och det andra för det tilldelade värdet.

Välj Flag när flera val ska kunna kombineras

En vanlig enum representerar normalt ett val åt gången. Om en användare däremot kan ha flera behörigheter samtidigt, som läsa och redigera, passar Flag bättre eftersom medlemmar kan kombineras med bitvisa operatorer.

from enum import Flag, auto

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

access = Permission.READ | Permission.EDIT

if Permission.EDIT in access:
    print("Redigering tillåten")

Flag håller kombinationen inom enum-typen. Välj IntFlag i stället om kombinationerna också måste fungera som heltal; vanlig aritmetik kan dock göra att resultatet inte längre är en enum-medlem.

Följ den här tumregeln när du väljer

Tänk på var värdet ska landa. Om det stannar i Python och ska uttrycka ett avgränsat alternativ, välj Enum; om ett gränssnitt kräver strängar eller heltal, välj motsvarande blandtyp; om alternativen ska kombineras, använd Flag.

SituationTrolig orsak eller följdGör så här
Jämförelse med "published" misslyckasDu jämför en vanlig Enum-medlem med dess råa strängvärde.Jämför med PageStatus.PUBLISHED eller använd status.value där en sträng behövs.
En enum-medlem skickas till ett bibliotek som kräver exakt strStrEnum är en underklass av str, men biblioteket kan kontrollera typen strikt.Prova str(member) vid just den gränsen.
Behörigheter ska kunna väljas i kombinationFlera oberoende flaggor behöver representeras samtidigt.Använd Flag eller IntFlag, inte en vanlig enum.
Två namn verkar peka på samma alternativMedlemmarna har fått identiska värden och ett alias har skapats.Lägg till @unique om varje värde ska ha ett enda namn.

För en webbplatsstatus som bara hanteras i Python skulle jag välja vanlig Enum; om samma värde måste skickas som text i ett API skulle jag välja StrEnum och kontrollera hur API-klienten hanterar typen. Den lilla skillnaden i definition kan förebygga en större felsökning vid systemgränsen.

Håll råvärdet stabilt när data sparas

En enum kan göra intern kod tydligare, men när värden sparas i en databas eller skickas över nätet blir de en del av ett gränssnitt. Välj därför värden med eftertanke och byt inte exempelvis "published" mot "live" utan att kontrollera befintlig lagring och konsumenter.

En enkel tumregel håller långt: använd Enum för strikt intern modellering, StrEnum eller IntEnum när kompatibilitet krävs, och Flag när flera val kan gälla samtidigt.

Vanliga frågor

Välj vanlig Enum när statusen främst används internt i Python och du vill hålla den åtskild från vanliga strängar. Välj StrEnum när värdet behöver fungera som en sträng, till exempel i ett API. StrEnum infördes i Python 3.11, och bibliotek som kontrollerar exakt typen str kan ändå kräva str(member).
En vanlig enum-medlem är ett eget enum-objekt, inte samma sak som dess råa strängvärde. Jämför med PageStatus.PUBLISHED när du arbetar med enum-medlemmar, eller använd status.value där en vanlig sträng behövs.
Som standard kan två medlemmar med samma värde bilda ett alias, där det senare namnet hänvisar till det första. Lägg till dekoratören @unique ovanför enum-klassen för att stoppa detta. Om två medlemmar delar värde, som PUBLISHED och LIVE, orsakar @unique ett ValueError.
Använd Flag när flera oberoende val kan gälla samtidigt, till exempel behörigheterna läsa och redigera. Medlemmar kan kombineras med bitvis operator, som Permission.READ | Permission.EDIT. Välj IntFlag om kombinationerna också måste fungera som heltal.
Betygsätt artikeln

Genomsnitt: 0.0 / 5 · 0 betyg

Taggar

python enum strenum intenum flag
Kommentarer (0)
Lägg till en kommentar