In Python 3.4, we got an Enum lib in the standard library: enum
. We can get a backport for enum
that works with Python 2.4 to 2.7 (and even 3.1 to 3.3), enum34 in pypi.
But we've managed to get along for quite some time without this new module - so why do we now have it?
I have a general idea about the purpose of enums from other languages. In Python, it has been common to use a bare class as follows and refer to this as an enum:
class Colors:
blue = 1
green = 2
red = 3
This can be used in an API to create a canonical representation of the value, e.g.:
function_of_color(Colors.green)
If this has any criticisms, it's mutable, you can't iterate over it (easily), and how are we to know the semantics of the integer, 2
?
Then I suppose I could just use something like a namedtuple, which would be immutable?
>>> Colors = namedtuple('Colors', 'blue green red')
>>> colors = Colors('blue', 'green', 'red')
>>> colors
Colors(blue='blue', green='green', red='red')
>>> list(colors)
['blue', 'green', 'red']
>>> len(colors)
3
>>> colors.blue
'blue'
>>> colors.index(colors.blue)
0
The creation of the namedtuple is a little redundant (we have to write each name twice), and so somewhat inelegant. Getting the "number" of the color is also a little inelegant (we have to write colors
twice). Value checking will have to be done with strings, which will be a little less efficient.
So back to enums.
What's the purpose of enums? What value do they create for the language? When should I use them and when should I avoid them?