Python 3.4 has a new enum module and Enum data type. If you are unable to switch to 3.4 yet, Enum has been backported.
Since Enum members support docstrings, as pre
Yes there is, and it's my favorite recipe so far. As a bonus, one does not have to specify the integer value either. Here's an example:
class AddressSegment(AutoEnum):
misc = "not currently tracked"
ordinal = "N S E W NE NW SE SW"
secondary = "apt bldg floor etc"
street = "st ave blvd etc"
You might ask why I don't just have "N S E W NE NW SE SW" be the value of ordinal? Because when I get its repr seeing gets a bit clunky, but having that information readily available in the docstring is a good compromise.
Here's the recipe for the Enum:
class AutoEnum(enum.Enum):
"""
Automatically numbers enum members starting from 1.
Includes support for a custom docstring per member.
"""
#
def __new__(cls, *args):
"""Ignores arguments (will be handled in __init__."""
value = len(cls) + 1
obj = object.__new__(cls)
obj._value_ = value
return obj
#
def __init__(self, *args):
"""Can handle 0 or 1 argument; more requires a custom __init__.
0 = auto-number w/o docstring
1 = auto-number w/ docstring
2+ = needs custom __init__
"""
if len(args) == 1 and isinstance(args[0], (str, unicode)):
self.__doc__ = args[0]
elif args:
raise TypeError('%s not dealt with -- need custom __init__' % (args,))
And in use:
>>> list(AddressSegment)
[, , , ]
>>> AddressSegment.secondary
>>> AddressSegment.secondary.__doc__
'apt bldg floor etc'
The reason I handle the arguments in __init__ instead of in __new__ is to make subclassing AutoEnum easier should I want to extend it further.