Iterate through a list calling functions

David Pratt fairwinds at eastlink.ca
Sun Jun 5 14:05:54 EDT 2005


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
>



More information about the Python-list mailing list