
Enum is great! Okay, okay, my opinion might be biased. ;)
There is one area where Enum is not great -- for a bunch of unrelated values. What would be nice is if we had something similar to Enum for the
- repr() - constantness of the name/value relationship
While I was looking in the stdlib for an example, I came across sre_constants, which was chock full of constants -- and it even has a minimal version of what I'm proposing:
class _NamedIntConstant(int): def __new__(cls, value, name): self = super(_NamedIntConstant, cls).__new__(cls, value) self.name = name return self
def __repr__(self): return self.name
My proposal, compared/contrasted with Enum:
like Enum, NamedValues will be in collections (a class) that will keep those names from being deleted or rebound to other values
like Enum, NamedValues will have `value` and `name` attributes, and also a `type` attribute
like Enum, NamedValues are attributes of their containing class
like Enum, iterating over the containing class will yield the names/values defined
like Enum, a class of NamedValues do not have to all be the same data type unless one is mixed in
like Enum, a particular name/value combination is a singleton
unlike Enum, duplicates are allowed
unlike Enum, new values can be added after class definition
unlike Enum, a NamedValue can always be used as-is, even if no data type has been mixed in -- in other words, there is no functional difference between MyIntConstants(int, NamedValue) and MyConstants(NamedValue).
If sre_constants was using a new data type, it should probably be IntEnum instead. But sre_parse is a good candidate for NamedValues:
class K(NamedValues): DIGITS = frozenset("0123456789")
OCTDIGITS = frozenset("01234567") HEXDIGITS = frozenset("0123456789abcdefABCDEF") ASCIILETTERS = frozenset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
WHITESPACE = frozenset(" \t\n\r\v\f")
_REPEATCODES = frozenset({MIN_REPEAT, MAX_REPEAT}) _UNITCODES = frozenset({ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY})
and in use:
>>> K.DIGITS K.DIGITS >>> K.DIGITS.name 'DIGITS' >>> K.DIGITS.value frozenset("0123456789")
Thoughts?
-- ~Ethan~