[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