Python Enums
By Flavio Copes
Learn how to use enums in Python by importing Enum from the enum module to bind readable names to constant values, then read them back with .value.
Enums are readable names that are bound to a constant value.
They exist to remove magic numbers from your code. Instead of scattering 0 and 1 around and having to remember that 0 means inactive, you give each value a name, and the code documents itself.
To use enums, import Enum from the enum standard library module:
from enum import Enum
Then you can initialize a new enum in this way:
class State(Enum):
INACTIVE = 0
ACTIVE = 1
Once you do so, you can reference State.INACTIVE and State.ACTIVE, and they serve as constants.
How do you read an enum value?
Now if you try to print State.ACTIVE for example:
print(State.ACTIVE)
it will not return 1, but State.ACTIVE.
The same value can be reached by the number assigned in the enum: print(State(1)) will return State.ACTIVE. Same for using the square brackets notation State['ACTIVE'].
You can however get the value using State.ACTIVE.value:
print(State.ACTIVE.value) # 1
And you can get the name as a string with name:
print(State.ACTIVE.name) # 'ACTIVE'
Listing and counting members
You can list all the possible values of an enum:
list(State) # [<State.INACTIVE: 0>, <State.ACTIVE: 1>]
You can count them:
len(State) # 2
And you can iterate over them directly:
for state in State:
print(state.name, state.value)
# INACTIVE 0
# ACTIVE 1
Comparing enum members
Members compare fine with each other:
State(1) == State.ACTIVE # True
But here’s the pitfall: an enum member is not equal to its raw value.
State.ACTIVE == 1 # False
This surprises people converting old code where 1 was used directly. A check like if status == 1 silently becomes always false. Compare against State.ACTIVE instead, or compare State.ACTIVE.value == 1.
If you really need members that behave like integers, the same module offers IntEnum.
Avoiding duplicate values
Two names can share the same value. Python makes the second one an alias of the first, and it disappears from iteration. If duplicates would be a bug in your case, use the @unique decorator:
from enum import Enum, unique
@unique
class State(Enum):
INACTIVE = 0
ACTIVE = 0
This raises ValueError: duplicate values found in <enum 'State'>: ACTIVE -> INACTIVE as soon as the class is defined, instead of letting the mistake hide in your code.
Related posts about python: