simples e flexivel {{{#!python class Enum(object): class EnumError(TypeError): pass def __init__(self): self.__dict__['__rdict__'] = {} # reverse dict, value => key self.__dict__['__ldict__'] = {} # labels dict, value => label def __setattr__(self, name, value): if name in self.__dict__: raise self.EnumError, "%s is a constant value" % name if not name.isupper(): raise NameError, 'enumeration constant %r not in uppercase' % name self.__dict__[name] = value self.__rdict__[value] = name def __delattr__(self, name): if name in self.__dict__: raise self.EnumError, "Cannot unbind constant %s" % name raise NameError, name def validate(self, value): if value not in self.__rdict__: raise ValueError('%s is not a valid enumeration constant value' % value) return True def key(self, value): if value not in self.__rdict__: raise ValueError('%s is not a valid enumeration constant value' % value) return self.__rdict__[value] def label(self, value): if value not in self.__rdict__: raise ValueError('%s is not a valid enumeration constant value' % value) return self.__ldict__.get(value) or self.__rdict__.get(value) def setlabel(self, value, label): if value not in self.__rdict__: raise ValueError('%s is not a valid enumeration constant value' % value) self.__ldict__[value] = label def simpletest(): Zakarias = Enum() Zakarias.ANNA = 1 Zakarias.BERNHARD = 2 Zakarias.CAESAR = 3 Zakarias.validate(Zakarias.ANNA) Zakarias.validate(Zakarias.BERNHARD) Zakarias.validate(Zakarias.CAESAR) assert Zakarias.key(Zakarias.ANNA) == 'ANNA' assert Zakarias.label(Zakarias.BERNHARD) == 'BERNHARD' Zakarias.setlabel(Zakarias.CAESAR, 'Caesar Constant') assert Zakarias.label(Zakarias.CAESAR) == 'Caesar Constant' def simpletest2(): FoneType = Enum() FoneType.PERSONAL = 1 FoneType.HOME = 2 FoneType.WORK = 3 FoneType.FAX = 4 class Internationalized(object): defaultlang = 'pt-br' def __str__(self, **args): return super(Internationalized, self).__str__() class EnumLabel(Internationalized): def __init__(self, labels): '''labels = {'lang': 'label', ...}''' self.labels = labels def __str__(self, lang=None): return self.labels[lang or self.defaultlang] FoneType.setlabel(FoneType.PERSONAL, EnumLabel({'en-us': 'personal', 'pt-br': 'pessoal'})) FoneType.setlabel(FoneType.HOME, EnumLabel({'en-us': 'home', 'pt-br': 'casa'})) FoneType.setlabel(FoneType.WORK, EnumLabel({'en-us': 'work', 'pt-br': 'trabalho'})) FoneType.setlabel(FoneType.FAX, EnumLabel({'en-us': 'fax', 'pt-br': 'fax'})) assert str(FoneType.label(FoneType.PERSONAL)) == 'pessoal' assert FoneType.label(FoneType.PERSONAL).__str__(lang='en-us') == 'personal' if __name__ == '__main__': simpletest() simpletest2() }}} == Observações == A [[http://www.python.org/dev/peps/pep-0354/|PEP 354]] já define Enumerators. Uma implementação dessa PEP pode ser vista no [[http://cheeseshop.python.org/pypi/enum/|Cheeseshop]]