Skip to content

Instantly share code, notes, and snippets.

@dimsmol
Created May 14, 2010
Embed
What would you like to do?
Enum implementation example
class Unset(object):
pass
class Item(object):
_cnt = 0
def __init__(self, value=Unset, choice=Unset):
self.key = None
self.value = value
self.choice = choice
self.num = Item._cnt
Item._cnt += 1
class EnumMeta(type):
def __new__(cls, name, bases, attrs):
items = []
for k, v in attrs.items():
if isinstance(v, Item):
v.key = k
if v.value is Unset:
v.value = k.lower()
if v.choice is Unset:
v.choice = k.capitalize()
items.append(v)
attrs[k] = v.value
items.sort(key=lambda item: item.num)
attrs['keys'] = [item.key for item in items]
attrs['values'] = [item.value for item in items]
if not 'choices' in attrs:
attrs['choices'] = tuple((item.value, item.choice) for item in items)
return super(EnumMeta, cls).__new__(cls, name, bases, attrs)
class Enum(object):
__metaclass__ = EnumMeta
@classmethod
def url_re(cls):
return '|'.join(str(v) for v in cls.values)
import enum
class TrackAction(enum.Enum):
PLAY = enum.Item()
STOP = enum.Item(choice='Stop! Stop!')
PAUSE = enum.Item(value='P')
print TrackAction.PLAY
# play
print TrackAction.STOP
# stop
print TrackAction.PAUSE
# P
print TrackAction.values
# ['play', 'stop', 'P']
print TrackAction.keys
# ['PLAY', 'STOP', 'PAUSE']
print TrackAction.choices
# (('play', 'Play'), ('stop', 'Stop! Stop!'), ('P', 'Pause'))
print r'^track/(?P<id>\d+)/(?P<event>'+TrackAction.url_re()+')/$'
# ^track/(?P<id>\d+)/(?P<event>play|stop|P)/$
# (can be used in urlconf)
@andreypopp
Copy link

andreypopp commented May 14, 2010

Enum inheritance does not work.

>>> import enum

>>> class A(enum.Enum):
...     a = enum.Item()

class B(A):
...     b = enum.Item()

>>> assert len(B.values) == 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

@dimsmol
Copy link
Author

dimsmol commented May 14, 2010

Thanks for your comment, Andrey.

You're right, inheritance doesn't work, it's just an example.
For now I'm happy with this naive implementation and not going to extend it.

But it's a good starting point from which anyone can fork and easily fix inheritance or add automatic numeric values generation or whatever he want :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment