patternpythonMinor
Yet another lightweight Enum for Python 2.7
Viewed 0 times
lightweightenumyetforanotherpython
Problem
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:
After reviewing the SO post here on recommendations for non-
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:
Each enum is then subclassed from this
The usage is working just as I want (except of course for #1), including for the IDE autocomplete of #2:
This construction is far more co
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 itemEach 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:
>>> myEnum.other
'other'
>>> 'this' in myEnum
True
>>> 'thing' in myEnum
False
>>> e = myEnum.other
>>> e in myEnum
TrueThis construction is far more co
Solution
An interesting bit of code. :)
The downsides would be the things missing from enum341:
Plus the surprise other developers will have when your
On the bright side, you shouldn't have any problems with pickling.
1 Disclosure: I am the author of the Python stdlib
2 See this answer for the standard
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,
iswon'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.Context
StackExchange Code Review Q#109724, answer score: 5
Revisions (0)
No revisions yet.