Cool! Many thanks George. Yes this is the way to go - objects. Much better :-)
On Sunday, June 5, 2005, at 02:49 PM, George Sakkis wrote: > David Pratt wrote: >> Hi. I am creating methods for form validation. Each validator has its >> own method and there quite a number of these. For each field, I want >> to evaluate errors using one or more validators so I want to execute >> the appropriate validator methods from those available. I am >> iterating >> over each validator using validateField method to gather my results. >> It >> works but it ugly and inefficient. Can someone advise whether there >> is >> a better way of doing this. I realize that the validator variable in >> my iteration is only a string so question is how can I make the >> validator string reference a function so I may be able to shorten >> validateField to something similar to this (instead of my long list of >> ifs which I am not very happy with): >> >> for validator in validators_list: >> result = validator(name, value) >> if type (result) in StringTypes: >> results[name] = result >> >> Many thanks >> David >> >> My current situation below: >> >> # A large list of validators >> def isDecimal(name, value): >> """ Test whether numeric value is a decimal """ >> result = validateRegex(name, >> value, >> r'^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$', >> errmsg='is not a decimal number.', >> ignore=None) >> return result >> >> def isZipCode(name, value): >> """ Tests if field value is a US Zip Code """ >> result = validateRegex(name, >> value, >> r'^(\d{5}|\d{9})$', >> errmsg='is not a valid zip code.', >> ignore=None) >> return result >> >> ... more validators >> >> # Iterating over validators to gather field errors >> def validateField(name, value, validators_list, range=None, >> valid_values=None): >> """ Validates field input """ >> results={} >> for validator in validators_list: >> if validator == 'isContainedIn': >> result = isContainedIn(name, value) >> if type (result) in StringTypes: >> more... >> if validator == 'isDate': >> result = isDate(name, value) >> if type (result) in StringTypes: >> more... >> if validator == 'isDecimal': >> result = isDecimal(name, value) >> if type (result) in StringTypes: >> more... >> >> more validators ... > > > That's a typical case for using an OO approach; just make a class for > each validator and have a single polymorphic validate method (I would > make validators __call__able instead of naming the method 'validate'): > > # Abstract Validator class; not strictly necessary but good for > documentation > class Validator(object): > def __call__(self,field,value): > '''Validate a value for this field. > Return a string representation of value on success, or None on > failure. > ''' > raise NotImplementedError("Abstract method") > > > class DecimalValidator(Validator): > def __call__(self,name,value): > '''Test whether numeric value is a decimal.''' > > class ZipCodeValidator(Validator): > def __call__(self,name,value): > '''Test if value is a US Zip Code.''' > > > def validateField(name, value, validators): > """ Validates field input """ > results = {} > for validate in validators: > result = validate(name,value) > if result is not None: > results[name] = result > # XXX: if more than one validators succeed, > # all but the last result will be overwritten > return results > > # test > validators = [DecimalValidator(), ZipCodeValidator()] > print validateField("home ZIP", "94303", validators) > > Regards, > George > > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list