Enums¶
Indices and tables¶
Definition¶
An enumeration is a set of names bound to unique, constant values. It associates friendly string names to constants.
Python doesn’t have a native enumeration type as part of the standard type hierarchy. Prior to Python 3.4 you could use namedtuple()
to work around this. However Python 3.4 introduced the enum
module (based on PEP 435) which is a cleaner way to create enums.
Tip
The namedtuple()
class has not been deprecated. It is a class for creating 1 or more objects that contain data accessible by name. An enumeration is a single object that associated a name with a constant value. It happened to be used in the past to mimic an enumeration but that does not mean it is now obsolete.
Two classes are now available for creating enumerations; Enum
and IntEnum
.
Enum¶
MUTABILITY: Immutable
Enums can be created in two ways, both of which create a new class in the namespace:
Using class based syntax, where you derive from
Enum
, and then add members with the names and values you want to associate with the enum. For example:>>> from enum import Enum >>> class Season(Enum): ... winter = 1 ... spring = 2 ... summer = 3 ... fall = 4
>>> dir(Season) ['__class__', '__doc__', '__members__', '__module__', 'fall', 'spring', 'summer', 'winter']
Using functional syntax, where you call the
Enum
constructor using the following general syntax:-
Enum
(name, field_iterable)¶
Where
name
is the name to give the enumeration.field_iterable
is a source of the enumeration member names and can be one of the following:A whitespace-separated string of names, as in:
>>> from enum import Enum >>> Seasons = Enum('Seasons', 'winter spring summer fall')
A list of names, as in:
>>> from enum import Enum >>> Seasons = Enum('Seasons', ['winter', ... 'spring', ... 'summer', ... 'fall'])
A list of 2-tuples with key/value pairs, as in:
>>> from enum import Enum >>> Seasons = Enum('Seasons', [('winter', 1), ... ('spring', 2), ... ('summer', 3), ... ('fall', 4)])
A mapping of names to values, as in:
>>> from enum import Enum >>> Seasons = Enum('Seasons', {'winter': 1, ... 'spring': 2, ... 'summer': 3, ... 'fall': 4})
-
Tip
The examples show enum member values sequentially from 1-4, but, this is not required. You can use any numbers and they need not be sequential. In fact, you don’t even need to use numbers as enum values can be any Python type! For example:
>>> from enum import Enum
>>> class Color(Enum):
... red = (255, 0, 0)
... green = (0, 255, 0)
... blue = (0, 0, 255)
>>> Color.red.value
(255, 0, 0)
Warning
You can’t have 2 enum members with the same name but you can have 2 enum members with the same value (the subsequent members alias’ the first).
In the above example, the enumeration is called “Season”.
The enumeration has the following 4 members:
- Season.winter
- Season.spring
- Season.summer
- Season.fall
The enumeration names are:
- winter
- spring
- summer
- fall
And the enumeration values are:
- 1
- 2
- 3
- 4
Each enumeration member is the type name of the enumeration:
>>> type(Season.winter)
<enum 'Season'>
Enum members print naturally:
>>> print(Season.winter)
Season.winter
You can also print the member names and values using pre-defined attributes name
and value
:
>>> print(Season.winter.name)
winter
>>> print(Season.winter.value)
1
You can iterate over enumeration members:
>>> for season in Seasons:
>>> print(season)
Seasons.summer
Seasons.fall
Seasons.spring
Seasons.winter
It is possible to access enumeration members by definition order using the callable-class syntax:
>>> Season(1)
<Season.winter: 1>
It is also possible to access enumeration members by name using the item access operator []
:
>>> Season['winter']
<Season.winter: 1>
The immutability of Enums means they are hashable and thus they can be used as keys in dictionaries and elements of sets. For example:
>>> favorite_sports = {}
>>> favorite_sports[Seasons.winter] = 'hockey'
>>> favorite_sports[Seasons.spring] = 'curling'
>>> favorite_sports[Seasons.summer] = 'baseball'
>>> favorite_sports[Seasons.fall] = 'football'
>>> favorite_sports
{<Seasons.fall: 4>: 'football',
<Seasons.spring: 2>: 'curling',
<Seasons.summer: 3>: 'baseball',
<Seasons.winter: 1>: 'hockey'}
Enum members support comparison. The preferred method is by identity using the is
operator as it is the fastest:
>>> Season.winter is Season.winter
True
>>> Season.winter is Season.fall
False
Although, the ==
and !=
operators are supported:
>>> Season.winter == Season.winter
True
>>> Season.winter == Season.fall
False
The operators, <
, <=
, >
and >=
are not supported by enum members and their use will throw a TypeError
.
The Enum
class does not support direct comparison to integers and will always return False
. For example, the following should intuitively be true, but returns false:
>>> Season.winter == 1
False
If you need to do comparisons to straight integers, use IntEnum
instead.
IntEnum¶
MUTABILITY: Immutable
The same as Enum
except it allows comparison to integers and not just to enum members. For example:
>>> from enum import IntEnum
>>> class Season(IntEnum):
... winter = 1
... spring = 2
... summer = 3
... fall = 4
>>> Season.winter == 1
True
Keep in mind that comparing a IntEnum
to a Enum
still returns False
, always.
Tip
Avoid the use of IntEnum
if you can. The reason being, due to the fact that you can compare to integers, that therefore allows you to compare to other unrelated enumerations, which can lead to unintentional errors. For example, although the following makes semantic sense, it is logically incorrect to compare these two classes together as they represent different types of information:
>>> from enum import IntEnum
>>> class Season(IntEnum):
... winter = 1
... spring = 2
... summer = 3
... fall = 4
>>> class FluSeverity(IntEnum):
... severe = 1
... moderate = 2
... low = 3
... mild = 4
>>> Season.winter == FluSeverity.severe
True
Try it!
Try the following:
Create an Enum class that assigns a value to the days of the week.
Return the value of the day, ‘Friday’.
Create an Enum class that assigns a value to the following terms:
- “Never”
- “Sometimes”
- “Always”
Using the 2 Enums created above, create a dictionary which maps the days of the week to whether we have to come to work.