I often find myself wanting an instance attribute that can take on only a few fixed symbolic values. (This is less functionality than an enum, since there are no *numbers* associated with the values). I do want the thing to fiercely object to assignments or comparisons with inappropriate values. My implementation below gets me:
.import mode .class C(object): . status = mode.Mode('started', 'done', 'on-hold') . .c=C() .c.status = 'started' .c.status = 'stated': #Exception raised .if c.status == 'done': something .if c.status == 'stated': #Exception raised .if c.status.done: something #simpler and clearer than string compare .if c.status < 'done': something # Mode arg strings define ordering I would appreciate comments on the overall scheme, as well as about the somewhat sneaky (I think) exporting of a property-factory instead of a class. My intent is to provide a simple clear interface to the client class ("C" above), but I don't want to do something *too* fragile or confusing... (I'd also welcome a better name than "Mode"...) -------------------------- mode.py ---------------------- class _Mode: #internal use only, not exported. def __init__(self, *vals): if [v for v in vals if not isinstance(v, str)]: raise ValueError, 'Mode values must be strings' else: self.values = list(vals) def set(self, val): if val not in self.values: raise ValueError, 'bad value for Mode: "%s"' % val else: self.state = val def __cmp__(self, other): if other in self.values: return cmp(self.values.index(self.state), self.values.index(other)) else: raise ValueError, 'bad value for Mode comparison' def __getattr__(self, name): if name in self.values: return self.state == name else: raise AttributeError, 'no such attribute: "%s"' % name def Mode(*vals): # *function* returning a *property*, not a class. m = _Mode(*vals) def _insert_mode_get(self): return m def _insert_mode_set(self, val): m.set(val) return property(_insert_mode_get, _insert_mode_set) ----------------------------------------------------------- Thanks, George -- http://mail.python.org/mailman/listinfo/python-list