(original) (raw)

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@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@python.org

https://mail.python.org/mailman/listinfo/python-dev

Unsubscribe: https://mail.python.org/mailman/options/python-dev/robertomartinezp%40gmail.com