associação pythonbrasil[11] django zope/plone planet Início Logado como (Entrar)

ConstantesEnumeradas

simples e flexivel

   1 class Enum(object):
   2     class EnumError(TypeError):
   3         pass
   4     
   5     def __init__(self):
   6         self.__dict__['__rdict__'] = {}     # reverse dict, value => key
   7         self.__dict__['__ldict__'] = {}     # labels dict, value => label
   8     
   9     def __setattr__(self, name, value):
  10         if name in self.__dict__:
  11             raise self.EnumError, "%s is a constant value" % name
  12         if not name.isupper():
  13             raise NameError, 'enumeration constant %r not in uppercase' % name
  14         self.__dict__[name] = value
  15         self.__rdict__[value] = name
  16     
  17     def __delattr__(self, name):
  18         if name in self.__dict__:
  19             raise self.EnumError, "Cannot unbind constant %s" % name
  20         raise NameError, name
  21     
  22     def validate(self, value):
  23         if value not in self.__rdict__:
  24             raise ValueError('%s is not a valid enumeration constant value' % value)
  25         return True
  26     
  27     def key(self, value):
  28         if value not in self.__rdict__:
  29             raise ValueError('%s is not a valid enumeration constant value' % value)
  30         return self.__rdict__[value]
  31     
  32     def label(self, value):
  33         if value not in self.__rdict__:
  34             raise ValueError('%s is not a valid enumeration constant value' % value)
  35         return self.__ldict__.get(value) or self.__rdict__.get(value)
  36     
  37     def setlabel(self, value, label):
  38         if value not in self.__rdict__:
  39             raise ValueError('%s is not a valid enumeration constant value' % value)
  40         self.__ldict__[value] = label
  41 
  42 def simpletest():
  43     Zakarias = Enum()
  44     Zakarias.ANNA = 1
  45     Zakarias.BERNHARD = 2
  46     Zakarias.CAESAR = 3
  47     
  48     Zakarias.validate(Zakarias.ANNA)
  49     Zakarias.validate(Zakarias.BERNHARD)
  50     Zakarias.validate(Zakarias.CAESAR)
  51 
  52     assert Zakarias.key(Zakarias.ANNA) == 'ANNA'
  53     assert Zakarias.label(Zakarias.BERNHARD) == 'BERNHARD'
  54     Zakarias.setlabel(Zakarias.CAESAR, 'Caesar Constant')
  55     assert Zakarias.label(Zakarias.CAESAR) == 'Caesar Constant'
  56 
  57 def simpletest2():
  58     FoneType = Enum()
  59     FoneType.PERSONAL = 1
  60     FoneType.HOME = 2
  61     FoneType.WORK = 3
  62     FoneType.FAX = 4
  63 
  64     class Internationalized(object):
  65         defaultlang = 'pt-br'
  66         def __str__(self, **args):
  67             return super(Internationalized, self).__str__()
  68 
  69     class EnumLabel(Internationalized):
  70         def __init__(self, labels):
  71             '''labels = {'lang': 'label', ...}'''
  72             self.labels = labels
  73         def __str__(self, lang=None):
  74             return self.labels[lang or self.defaultlang]
  75 
  76     FoneType.setlabel(FoneType.PERSONAL, EnumLabel({'en-us': 'personal', 'pt-br': 'pessoal'}))
  77     FoneType.setlabel(FoneType.HOME, EnumLabel({'en-us': 'home', 'pt-br': 'casa'}))
  78     FoneType.setlabel(FoneType.WORK, EnumLabel({'en-us': 'work', 'pt-br': 'trabalho'}))
  79     FoneType.setlabel(FoneType.FAX, EnumLabel({'en-us': 'fax', 'pt-br': 'fax'}))
  80 
  81     assert str(FoneType.label(FoneType.PERSONAL)) == 'pessoal'
  82     assert FoneType.label(FoneType.PERSONAL).__str__(lang='en-us') == 'personal'
  83 
  84 if __name__ == '__main__':
  85     simpletest()
  86     simpletest2()

Observações

A PEP 354 já define Enumerators.

Uma implementação dessa PEP pode ser vista no Cheeseshop