I'd like to have an Abstract Data Type for a scalar value that is
restricted to a small set of values. Like an Enum, I suppose.
What I would like is to be able to use simple 'str' values in most of
the code, but where the values are actually used in a semantically
meaningful context, have them used as an ADT that will barf if the
value isn't part of the set.
Using the HumanSex class example from an earlier thread:
class HumanSex(str):
_descriptions = {
None: "unknown",
'male': "Male",
'female': "Female",
}
def __init__(self, value):
str.__init__(value)
if value not in self._descriptions:
raise ValueError, \
"Not a valid HumanSex value: '%s'" % value
def __get_description(self):
return self._descriptions[self]
description = property(__get_description)
This way, most of the rest of the code doesn't need to know that the
HumanSex instances are anything but a simple 'str' value.
Is this a sensible way to do what I'm describing? Am I missing a
common programming pattern?
--
\ "I bought a self learning record to learn Spanish. I turned it |
`\ on and went to sleep; the record got stuck. The next day I |
_o__) could only stutter in Spanish." -- Steven Wright |
Ben Finney
How about this:
class BaseEnum(str):
"""Base class for enumerations. You must subclass and provide
values for the _valid list."""
_valid = []
def __init__(self, v):
assert self in self._valid, 'value %r not in %r' % (self,
self._valid)
cass Gender(BaseEnum):
_valid = ['male', 'female', 'unknown']
Trying the following:
Gender('male')
Gender('female')
assert Gender('male') == 'male'
Gender('shemale')
The last will return an error:
AssertionError: value 'shemale' not in ['male', 'female', 'unknown']
Graham