Enums are cool after all
I made a lot of time that Enum were a coo thing in Python. Before that, I thought that I could achieve the same result with a bunch of constants and dicts. In my current project, I found myself using them all over the place.
Enum exists in a lot of languages, from C to Java. It is basically a set of possible integer values, labeled with a name. For instance, Spring, Summer, Autumn and Winter could be a nice Enum.
A specific structure is not necessary to do so, as you can achieve the same goal with simple integer constants. But Enum cares about the boring stuff for you. Quick tour.
Import the Enum base class to start playing with Enum (I leave the ipython beginning of lines)
In : from enum import Enum
You can then create your first Enum
In : class Season(Enum): ...: SPRING = 0 ...: SUMMER = 1 ...: AUTUMN = 2 ...: WINTER = 3
And instantiate a member
In : s = Season.SUMMER
You can access a string representation of the enum member, its value and name
In : s Out: <Season.SUMMER: 1> In : str(s) Out: 'Season.SUMMER' In : s.name Out: 'SUMMER' In : s.value Out: 1
Enums are good to compare values in a readable way
In : s == Season(1) Out: True
Another cool stuff is the ability to return all enum possible value as a list
In : list(Season) Out: [<Season.SPRING: 0>, <Season.SUMMER: 1>, <Season.AUTUMN: 2>, <Season.WINTER: 3>]
You are not obliged to set the integer values manually as enum package provides auto function to do it for you, starting with 1.
In : from enum import auto In : class Season2(Enum): ...: SPRING = auto() ...: SUMMER = auto() ...: AUTUMN = auto() ...: WINTER = auto() ...: In : Season2.SPRING Out: <Season2.SPRING: 1> In : list(Season2) Out: [<Season2.SPRING: 1>, <Season2.SUMMER: 2>, <Season2.AUTUMN: 3>, <Season2.WINTER: 4>]
You can start with the value you want, then user auto to increment it.
In : class Season4(IntEnum): ...: SPRING = 0 ...: SUMMER = auto() ...: AUTUMN = auto() ...: WINTER = auto() In : list(Season4) Out: [<Season4.SPRING: 0>, <Season4.SUMMER: 1>, <Season4.AUTUMN: 2>, <Season4.WINTER: 3>]
Unfortunately, you cannot compare an Enum member with an int directly
In : Season2.SPRING == 1 Out: False In : Season2.SUMMER == 2 Out: False
But you can use IntEnum alternative to do so. Its an enum that subclasses the int class to ease comparison and affectation. It can be a good idea if you use enum along with integer fields in a database.
In : from enum import IntEnum In : class Season3(IntEnum): ...: SPRING = auto() ...: SUMMER = auto() ...: AUTUMN = auto() ...: WINTER = auto() In : Season3.SUMMER == 2 Out: True
And last but not least, as Enum is a class, you can add methods to customize instantiation and representation.
Nowadays, I like using Enum to define integer choices for db fields in Django, thanks to the list representation of enum members. It help me to keep the code base readable and add namespacing rather than using individual constants.
So it's cool stuff, easy to use, that you should consider for your next project.
Posted on 2019-09-17 at 23:00Previous Back