1"""\ 2Generic enumeration support. 3""" 4 5__author__ = 'showard@google.com (Steve Howard)' 6 7class Enum(object): 8 """\ 9 Utility class to implement Enum-like functionality. 10 11 >>> e = Enum('String one', 'String two') 12 >>> e.STRING_ONE 13 0 14 >>> e.STRING_TWO 15 1 16 >>> e.choices() 17 [(0, 'String one'), (1, 'String two')] 18 >>> e.get_value('String one') 19 0 20 >>> e.get_string(0) 21 'String one' 22 23 >>> e = Enum('Hello', 'Goodbye', string_values=True) 24 >>> e.HELLO, e.GOODBYE 25 ('Hello', 'Goodbye') 26 27 >>> e = Enum('One', 'Two', start_value=1) 28 >>> e.ONE 29 1 30 >>> e.TWO 31 2 32 """ 33 def __init__(self, *names, **kwargs): 34 self.string_values = kwargs.get('string_values') 35 start_value = kwargs.get('start_value', 0) 36 step = kwargs.get('step', 1) 37 self.names = names 38 self.values = [] 39 for i, name in enumerate(names): 40 if self.string_values: 41 value = name 42 else: 43 value = i * step + start_value 44 self.values.append(value) 45 setattr(self, self.get_attr_name(name), value) 46 47 48 @staticmethod 49 def get_attr_name(string): 50 return string.upper().replace(' ', '_') 51 52 53 def choices(self): 54 'Return choice list suitable for Django model choices.' 55 return zip(self.values, self.names) 56 57 58 def get_value(self, name): 59 """\ 60 Convert a string name to it's corresponding value. If a value 61 is passed in, it is returned. 62 """ 63 if isinstance(name, (int, long)) and not self.string_values: 64 # name is already a value 65 return name 66 return getattr(self, self.get_attr_name(name)) 67 68 69 def get_string(self, value): 70 ' Given a value, get the string name for it.' 71 if value not in self.values: 72 raise ValueError('Value %s not in this enum' % value) 73 index = self.values.index(value) 74 return self.names[index] 75