Pages

Sep 25, 2013

First look at Python enums (part 1)

The major novelty in the upcoming Python 3.4 is the addition of an Enum type. If you've ever written code in C, C#, C++ or Java, you've already encountered enumerations and know what they are. If not, here's how Wikipedia defines them:

[A]n enumerated type (also called enumeration or enum […]) is a data type consisting of a set of named values called elements, members or enumerators of the type. The enumerator names are usually identifiers that behave as constants in the language. A variable that has been declared as having an enumerated type can be assigned any of the enumerators as a value.

It'll all make more sense once we start writing some code, but first there's some preliminary work to do.

Installing Enums

As mentioned Enums are available starting Python 3.4. At the time of this writing, the alpha2 has been published so you can go grab it (and start bug hunting). Enums have also been backported to every version after 2.4 in a separate package called enum34 available on PyPI.

Note that we are checking for similarity by comparing identities and not values. We'll cover this some more in later paragraphs.

An enum member has a value

You might have noticed when defining or WeekDays Enum that we're assigning a value for each member of the enumeration. These values aren't really meant to mean or represent anything, especially since enumeration members don't support comparison. We'll talk in length about comparison, values and identity in the second part of this article. For now, just remember that you need to give a distinct value for each member. In most cases, numerical values in increasing orders would be enough.

If the value is meaningless, why do we explicit it?

It has been discussed that it would make it easier to have the enum assign a random value to each member implicitly.

Setting aside the challenges that might occur from ensuring that each of these value is unique, the Python dev have opted out, since it would take too much "magic" to make it happen, and would hide too much the details of implementation.

After all, the Zen of Python tells us that "explicit is better than implicit", right?

Access

You can access the value of a enum member by examining the value attribute:

assert(WeekDays.Monday.value == 1)

The value can be used to retrieve a member by calling the class:

assert(WeekDays(1) is WeekDays.Monday)

Functional API

It is possible to assign numerical values of increasing orders automatically, using what has been called the "Functional API".
To understand the syntax, here's the exact same definition of the WeekDays enum, using the functional API: