[Tutor] Iterate through a list calling functions

Kent Johnson kent37 at tds.net
Mon Jun 6 03:53:16 CEST 2005


David Pratt wrote:
> Hi Kent.  Thank you for your reply.  I gave this a go but get the 
> following traceback:
> ...
>     result = validator(name, value)
> TypeError: 'str' object is not callable
> 
> Have put validators in list and iterate over it as in following:
> 
>     validator_list = 
> [isContainedIn,isDate,isDecimal,isEmail,isEmpty,isInteger...
>          more validators....]   
>     results={}
>     for validator in validators_list:
>         result = validator(name, value)
>         if type (result) in StringTypes:
>             # do some stuff...
>     return results
> 

Are you sure you don't have quoted strings in your validator list? 
That is what the error message indicates. Can you post a small complete 
example of the code that fails?

or put
print repr(validator)

before the line that calls validator so you can see exactly what you are trying to call.

Kent

> Regards,
> David
> 
> 
> On Sunday, June 5, 2005, at 02:03 PM, Kent Johnson 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
>>
>>
>> Actually you can do exactly that by putting references to the 
>> validator functions in your list instead of (string) name. For example 
>> if you have
>> validators = [ 'isDecimal', 'isFoo', 'isBar' ]
>>
>> just change it to
>> validators = [ isDecimal, isFoo, isBar ]
>>
>> and your loop above will work.
>>
>> Python makes data-driven programming easy :-)
>> Kent
>>
>>>
>>> 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 ...
>>>
>> -- 
>> http://mail.python.org/mailman/listinfo/python-list
>>
> 



More information about the Tutor mailing list