Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ADT for restricted set of values

0 views
Skip to first unread message

Ben Finney

unread,
Nov 3, 2005, 7:56:05 PM11/3/05
to
Howdy all,

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

Graham Fawcett

unread,
Nov 3, 2005, 8:11:43 PM11/3/05
to
Ben Finney wrote:
> Howdy all,
>
> 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.

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

0 new messages