[Python-Dev] AutoNumber Enum

Roberto Martínez robertomartinezp at gmail.com
Wed Jun 29 18:40:50 EDT 2016


Why the 'start' parameter default is 1? 0 (zero) is more consistent with
other parts of the language: indexes, enumerate, range...

El mié., 29 de jun. de 2016 21:26, Ethan Furman <ethan at stoneleaf.us>
escribió:

> On 06/29/2016 12:11 PM, Guido van Rossum wrote:
>
> > And how would you implement that without support from the compiler?
> > Does it use a hook that catches the NameError?
>
> It's built into the _EnumDict class dictionary used during class creation.
>
> Current (edited) code from the aenum package that implements this:
>
> class _EnumDict(dict):
>      """Track enum member order and ensure member names are not reused.
>
>      EnumMeta will use the names found in self._member_names as the
>      enumeration member names.
>      """
>      def __init__(self, locked=True, start=1, multivalue=False):
>          super(_EnumDict, self).__init__()
>          # list of enum members
>          self._member_names = []
>          # starting value for AutoNumber
>          self._value = start - 1
>          # when the magic turns off
>          self._locked = locked
>          ...
>
>      def __getitem__(self, key):
>          if (
>                  self._locked
>                  or key in self
>                  or _is_sunder(key)
>                  or _is_dunder(key)
>                  ):
>              return super(_EnumDict, self).__getitem__(key)
>          try:
>              # try to generate the next value
>              value = self._value + 1
>              self.__setitem__(key, value)
>              return value
>          except:
>              # couldn't work the magic, report error
>              raise KeyError('%s not found' % key)
>
>      def __setitem__(self, key, value):
>          """Changes anything not sundured, dundered, nor a descriptor.
>          Single underscore (sunder) names are reserved.
>          """
>          if _is_sunder(key):
>              raise ValueError('_names_ are reserved for future Enum use')
>          elif _is_dunder(key):
>              if key == '__order__':
>                  key = '_order_'
>              if _is_descriptor(value):
>                  self._locked = True
>          elif key in self._member_names:
>              # descriptor overwriting an enum?
>              raise TypeError('Attempted to reuse name: %r' % key)
>          elif not _is_descriptor(value):
>              if key in self:
>                  # enum overwriting a descriptor?
>                  raise TypeError('%s already defined as: %r' % ...
>              self._member_names.append(key)
>              if not self._locked:
>                  if isinstance(value, int):
>                      self._value = value
>                  else:
>                      count = self._value + 1
>                      self._value = count
>                      value = count, value
>          else:
>              # not a new member, turn off the autoassign magic
>              self._locked = True
>          super(_EnumDict, self).__setitem__(key, value)
>
> Disclaimer:  some errors may have crept in as I deleted unrelated
> content.  For the full code check out the _EnumDict class in the aenum
> package.
>
> --
> ~Ethan~
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/robertomartinezp%40gmail.com
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20160629/a87a999d/attachment.html>


More information about the Python-Dev mailing list