Understanding Python Enum Basics

The Python Standard Library provides a library to create Enumeration data types. This can be a convenient way to create aliases for ordinal references:

from enum import Enum

class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3

print(Color.RED, Color.RED.value)       # Returns Color.RED 1

Now we can use Color.RED or Color.RED.value as a reference, rather than remember what index it has.

Using Enum auto() for Automatic Value Assignment

The Enum library also provides a convivence function auto() that automatically increments each value, so that we don't need to manually set each one.

class Color2(Enum):
    RED = auto()
    GREEN = auto()
    BLUE = auto()

print(Color2.RED, Color.RED.value)      # Returns Color2.RED 1
print(Color2.GREEN, Color.GREEN.value)  # Returns Color2.GREEN 2

Note that auto() starts at one by default, not zero.

Starting Enum auto() at a custom value

Sometimes we might want our Enum values to start from a value other than one. The simplest pattern I've found is by manually setting the first value, and then calling auto() for subsequent values. This works because:

auto can be used in place of a value. If used, the Enum machinery will call an Enum's _generate_next_value_() to get an appropriate value. For Enum … that appropriate value will be the last value plus one
class enum.auto

Python Enum Example using Pygame Custom Events

This is useful when creating custom events in Pygame, as the library already defines thousands of built-in event types. Custom events therefore must not use these existing event indexes. Fortunately, pygame provides pygame.USEREVENT, which provides the index of the next available index. 

from enum import Enum, auto
import pygame

class CustomEvent(Enum):
    FirstEvent = pygame.USEREVENT
    SecondEvent = auto()
    ThirdEvent = auto()

print(f"pygame.USEREVENT: {pygame.USEREVENT}")
for event in CustomEvent:
    print(f"{event.name}: {event.value}")

# Output:
# pygame.USEREVENT: 32850
# FirstEvent: 32850
# SecondEvent: 32851
# ThirdEvent: 32852

Now we don't have to worry about manually managing the values of each event. We have also future-proofed our code in the event pygame increases the number of reserved event indexes.

Reinforcing Knowledge with Anki Cards

To ensure I remember this pattern, I made myself some simple Anki cards.

Setting custom Enum auto() start value

Front

How to create a Python Enum that starts at a custom value?

Back

Set first parameter to custom value, then use auto().

from enum import Enum, auto

n = 100
class MyEnum(Enum):
    FIRST = n
    SECOND = auto()
    THIRD = auto()
for e in MyEnum:
    print(f"{e.name}: {e.value}")
# Output:
# FIRST: 100
# SECOND: 101
# THIRD: 102

Enum's auto() start value

Front

What value does Python Enum auto() start at?

Back

One.

from enum import Enum, auto

class MyEnum(Enum):
    FIRST = auto()
print(f"{MyEnum.FIRST.name}: {MyEnum.FIRST.value}")
# Output: FIRST: 1