Yet another lightweight Enum for Python 2.7 I'm trying to develop a lightweight enum for Python 2.7.  This question is downstream of the SO question here; for context, a streamlined version of the bulleted addendum to that question is replicated below:


  My desired feature set is:
  
  
  Only having to type the enum name (or value) once in the source definition.
  Valid enum values exposed for IDE autocomplete.
  Enum values stored internally as comprehensible strings.
  Straightforward membership testing using native Python in.
  Ability to import individual enum subclasses via, say, from .enums import myEnum, to avoid cluttering the local namespace with other enums I don't care about.
  I would rather avoid introducing an additional package dependency by using enum34, as I don't (think I) need the feature set.
  


After reviewing the SO post here on recommendations for non-enum34 implementations of enums in Python 2.7, I also would add:


  
  Clean, readable definition of enum values.
  


To note, every form of dynamic namespace construction I've tried, in efforts to accomplish #1, has broken #2.  I'm pretty sure at this point they're mutually exclusive.

In any event, my current solution goes as follows, defining an enum superclass with a metaclassed type with an iterator that returns all members with string content identical to the respective member names:

class SuperEnum(object):
    class __metaclass__(type):
        def __iter__(self):
            for item in self.__dict__:
                if item == self.__dict__[item]:
                    yield item


Each enum is then subclassed from this SuperEnum, e.g.:

class myEnum(SuperEnum):
    this = 'this'
    that = 'that'
    other = 'other'


The usage is working just as I want (except of course for #1), including for the IDE autocomplete of #2:

&gt;&gt;&gt; myEnum.other
'other'
&gt;&gt;&gt; 'this' in myEnum
True
&gt;&gt;&gt; 'thing' in myEnum
False
&gt;&gt;&gt; e = myEnum.other
&gt;&gt;&gt; e in myEnum
True


This construction is far more concise than anything I'd set up around the time I posted the above-linked SO question, so the need to type the value name twice in the enum class definition isn't terribly bothersome.  I'm still interested to know if there's any way to make #1 and #2 play nice together, though.

More generally: what might the weaknesses of this construction be? For my application, performance is of minor concern. There's always the possibility of value collisions, as described here, but using strings as the values dramatically reduces the likelihood.  Security issues? Compatibility problems of some kind?
An interesting bit of code.  :)

The downsides would be the things missing from enum341:


printing a variable gives no indication that it's an enum and not a string
enums that have the same value will compare equal
depending on the value of the member, is won't always work
etc.


Plus the surprise other developers will have when your enum doesn't work like the now-standard Python Enum2.

On the bright side, you shouldn't have any problems with pickling.



1 Disclosure:  I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum)  library.

2 See this answer for the standard Enum usage.