Created
May 14, 2010 19:28
-
-
Save dimsmol/401547 to your computer and use it in GitHub Desktop.
Enum implementation example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
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
Enum inheritance does not work.