Code included below. Basically, I've created a series of "question" descriptors, which each hold a managed value. This is so I can implement validation, and render each field into html automatically for forms.
My problem is this: every instance of my "wizard" class has unique self values, but they share the exact same descriptor values. Meaning, if t = Test("ar") y = Test("ar") t is y False t.age is y.age True t.age = 9 y.age 9 Code below. What am I not understanding? ----------------------------------------- import datetime, re class Question(object): def __init__(self, qtext, name, default=None, required=False, max_length=None, choices=None): self._name = name self._qtext = qtext self._value = default self._error = None self._max_length = max_length self._required = required self._choices = choices def __get__(self, instance, owner): return self def __set__(self, instance, value): error = self.validate(value) if not error: self._value = self.cast(value) self._error = None else: self._value = value self._error = error print error def __str__(self): return str(self._value) def __repr__(self): return str(self._value) def cast(self, value): return value def validate(self, value): return True def html(self): #ugly html renderer removed; irrelevant to problem return html def error(self): if self._error: return True class Q_Integer(Question): def validate(self, value): if self._required and not value: return "Field is required." elif not value: return None try: int(value) return None except: return "Answer must be a whole number." def cast(self, value): if value: return int(value) class Q_Float(Question): def validate(self, value): if self._required and not value: return "Field is required." elif not value: return None try: float(value) return None except: return "Answer must be a decimal number." def cast(self, value): if value: return float(value) class Q_Chars(Question): def validate(self, value): try: if self._required and not value: return "Field is required." elif not value: return None if self._max_length: if len(value) > self._max_length: return "Too many characters; max of %s allowed." % self._max_length return None except: return "Invalid entry." def cast(self, value): if value: return str(value) class Q_Long(Question): def validate(self, value): try: if self._required and not value: return "Field is required." elif not value: return None except: return "Invalid entry." def cast(self, value): if value: return str(value) def html(self): #ugly html renderer removed; irrelevant to problem return html class Q_Bool(Question): def validate(self, value): return None def cast(self, value): return bool(value) def html(self): #ugly html renderer removed; irrelevant to problem return html class Q_Phone(Question): def validate(self, value): try: if self._required and not value: return "Field is required." elif not value: return None pieces = value.split("-") if len(pieces[0]) == 3 and len(pieces[1]) == 3 and len(pieces[2]) == 4: int(pieces[0]) int(pieces[1]) int(pieces[2]) return None else: return "Requires Valid Phone Number in XXX-XXX-XXXX format." except: return "Requires Valid Phone Number in XXX-XXX-XXXX format." class Q_Date(Question): def validate(self, value): try: if self._required and not value: return "Field is required." elif not value: return None r = re.compile(r"\d{1,2}[-/.]\d{1,2}[-/.]\d{1,4}") month, day, year = r.findall(value)[0].replace("/","-").replace(".","-").split("-") date = datetime.date(year=int(year), month=int(month), day=int(day) ) return None except: return "Requires valid date in mm-dd-yy format." def cast(self, value): if value: r = re.compile(r"\d{1,2}[-/.]\d{1,2}[-/.]\d{1,4}") month, day, year = r.findall(value)[0].replace("/","-").replace(".","-").split("-") year = int(year) if year < 70: year += 2000 elif year < 100: year += 1000 date = datetime.date(year=int(year), month=int(month), day=int(day) ) return date def __str__(self): date = self._value return "%s/%s/%s" % (date.month, date.day, date.year) ## Wizard Base Object class Wizard(object): def __init__(self, action): self.action = action self.init_time = datetime.datetime.now() pagediv = "box" title = "A Dynamic Wizard" instructions = "There are no real instructions here. Sorry." grouping = [ ] def render_form(self): #ugly html renderer removed; irrelevant to problem return form def flatten(self, post): for key in post: if not key == "command": errors = "" cblock = "self.%s = '%s'\n" % (key, post[key]) ab_save = compile( cblock, errors, 'exec') exec(ab_save) def errorcheck(self): error = 0 for section in self.grouping: for question in section: t = eval( "self.%s.validate(self.%s._value)" % (question, question) ) if t: error = 1 return error C_CHOICES = ( ("red", "Red"), ("blue", "Blue"), ("green", "Green"), ) class Test(Wizard): grouping = [ [ 'age', 'weight' ], [ 'feet', 'inches' ], ['name', 'cash', 'fav_color', 'happy', 'birthday'] ] def __new__(self): age = Q_Integer("Your Age:", "age", 99) weight = Q_Integer("Your Weight:", "weight", 200) feet = Q_Integer("Feet tall:", "feet", 6) inches = Q_Integer("Inches Tall:", "inches", 0) name = Q_Chars("Your Name:", "name", max_length=15, required=True) cash = Q_Float("Money in hand?", "cash", required=True, default=55.50) fav_color = Q_Chars("Your favorite color?", "fav_color", required=True, max_length=50, choices=C_CHOICES) homezip = Q_Zip("Your zip code?", "homezip", required=True, ) happy = Q_Bool("Are you happy?", "happy", default=False) birthday = Q_Date("Your Birthday:", "birthday") -- http://mail.python.org/mailman/listinfo/python-list