I prefer the Michael Ford proposed syntax and would gladly port the implementation if possible.
Having to specify either an ordinal number like in BASIC of 1980 or have to specify symbols as strings looks dodgy to me.
Michael Ford's proposed syntax looks much nicer. I don't understand why the enum values have to be assigned when they are first looked up. Why couldn't the commas in the definition signal that the enum members should have automatic values assigned at the definition?
I'm not convinced it's useful to pass the class name into the functional API, but I would see value in having an easy API to create enumerated strings. It's easier to see what's going on in other environments (e.g. in a datastore, or in JavaScript) if you pass around string identifiers instead of ints.
Here's the class I've been using to do that:
class Constants(object):
def __init__(self, names, enum = False):
self._names = frozenset(names)
if enum:
for (i, name) in enumerate(self._names):
setattr(self, name.upper(), i)
else:
for name in self._names:
setattr(self, name.upper(), name.lower())
self.frozen = True
def keys(self):
return [name.upper() for name in self._names]
def values(self):
return [getattr(self, name.upper()) for name in self._names]
def __setattr__(self, key, value):
if getattr(self, 'frozen', False):
raise Exception("Constants cannot be modified after instantiation")
else:
object.__setattr__(self, key, value)
There is a technical reason why the class name is passed into the API, and it's the same for other functions which create types (collections.namedtuple(), and type(), for example). You want to be able to print out the class name when you print an enum, but there is no other reliable way to figure out the class name. In Python, a class is just another value, like functions and integers and its name is nothing special. When you define a class normally, the name and dictionary get passed to the type() function.
I understand that, but I'm not sure it matter. Is it worth the ugliness in the API to print out the class name when you run print? Is 'api' that much worse than "ImportMethod.API"?
That's not all it's there for. Python programmers expect to be able to do things like print(obj.__class__.__name__). You're definitely free to write your own alternative Enum, however, since it's just a library function.