The Python Oracle

What's the common practice for enums in Python?

--------------------------------------------------
Hire the world's top talent on demand or became one of them at Toptal: https://topt.al/25cXVn
and get $2,000 discount on your first invoice
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: City Beneath the Waves Looping

--

Chapters
00:00 What'S The Common Practice For Enums In Python?
00:19 Answer 1 Score 21
00:48 Answer 2 Score 9
01:25 Accepted Answer Score 374
01:53 Answer 4 Score 6
02:06 Thank you

--

Full question
https://stackoverflow.com/questions/7028...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #enums

#avk47



ACCEPTED ANSWER

Score 374


class Materials:
    Shaded, Shiny, Transparent, Matte = range(4)

>>> print Materials.Matte
3

Update: For Python 3.4+:

As of Python 3.4+, you can now use Enum (or IntEnum for enums with int values) from the enum module. Use enum.auto to increment the values up automatically:

import enum


class Materials(enum.IntEnum):
    Shaded = 1
    Shiny = enum.auto()
    Transparent = 3
    Matte = enum.auto()


print(Materials.Shiny == 2)  # True
print(Materials.Matte == 4)  # True



ANSWER 2

Score 21


I've seen this pattern several times:

>>> class Enumeration(object):
        def __init__(self, names):  # or *names, with no .split()
            for number, name in enumerate(names.split()):
                setattr(self, name, number)

>>> foo = Enumeration("bar baz quux")
>>> foo.quux
2

You can also just use class members, though you'll have to supply your own numbering:

>>> class Foo(object):
        bar  = 0
        baz  = 1
        quux = 2

>>> Foo.quux
2

If you're looking for something more robust (sparse values, enum-specific exception, etc.), try this recipe.




ANSWER 3

Score 9


I have no idea why Enums are not support natively by Python. The best way I've found to emulate them is by overridding _ str _ and _ eq _ so you can compare them and when you use print() you get the string instead of the numerical value.

class enumSeason():
    Spring = 0
    Summer = 1
    Fall = 2
    Winter = 3
    def __init__(self, Type):
        self.value = Type
    def __str__(self):
        if self.value == enumSeason.Spring:
            return 'Spring'
        if self.value == enumSeason.Summer:
            return 'Summer'
        if self.value == enumSeason.Fall:
            return 'Fall'
        if self.value == enumSeason.Winter:
            return 'Winter'
    def __eq__(self,y):
       return self.value==y.value

Usage:

>>> s = enumSeason(enumSeason.Spring)

>>> print(s)

Spring



ANSWER 4

Score 6


You could probably use an inheritance structure although the more I played with this the dirtier I felt.

class AnimalEnum:
  @classmethod
  def verify(cls, other):
    return issubclass(other.__class__, cls)


class Dog(AnimalEnum):
  pass

def do_something(thing_that_should_be_an_enum):
  if not AnimalEnum.verify(thing_that_should_be_an_enum):
    raise OhGodWhy