try/except in a loop

Jean-Michel Pichavant jeanmichel at sequans.com
Thu May 3 10:54:05 EDT 2012


Peter Otten wrote:
> Jean-Michel Pichavant wrote:
>
>   
>> Chris Kaynor wrote:
>>     
>>> On Wed, May 2, 2012 at 12:51 PM, J. Mwebaze <jmwebaze at gmail.com> wrote:
>>>   
>>>       
>>>> I have multiple objects, where any of them can serve my purpose..
>>>> However some objects might not have some dependencies. I can not tell
>>>> before hand if the all the dependencies exsit. What i want to is begin
>>>> processing from the 1st object, if no exception is raised, i am done..
>>>> if an exception is
>>>> raised, the next object is tried, etc  Something like
>>>>
>>>> objs = [... ]
>>>> try:
>>>>   obj = objs[0]
>>>>   obj.make()
>>>> except Exception, e:
>>>>   try:
>>>>       obj = objs[1]
>>>>       obj.make()
>>>>   except Exception, e:
>>>>      try:
>>>>         obj = objs[2]
>>>>         obj.make()
>>>>      except Exception, e:
>>>>        continue
>>>>
>>>> The problem is the length of the list of objs is variable... How can i
>>>> do this?
>>>>     
>>>>         
>>> for obj in objs:
>>>     try:
>>>         obj.make()
>>>     except Exception:
>>>         continue
>>>     else:
>>>         break
>>> else:
>>>     raise RuntimeError('No object worked')
>>>
>>>   
>>>       
>> For the record, an alternative solution without try block:
>>     
>
> Hmm, it's not sufficient that the method exists, it should succeed, too.
>
> class Obj:
>     def make(self):
>         raise Exception("I'm afraid I can't do that")
> objs = [Obj()]
>
>   
>> candidates = [obj for obj in objs if hasattr(obj, 'make') and
>> callable(obj.make)]
>> if candidates:
>>     candidates[0].make()
>>     
>
> It is often a matter of taste, but I tend to prefer EAFP over LBYL.
>
>   
Could be that the OP did its job by calling the make method if it 
exists. If the method raises an exception, letting it through is a 
viable option if you cannot handle the exception.
Additionaly, having a method not raising any exception is not a criteria 
for success, for instance

def make(self):
    return 42

will surely fail to do what the OP is expecting.

By the way on a unrelated topic, using try blocks to make the code 
"robust" is never a good idea, I hope the OP is not try to do that.

JM




More information about the Python-list mailing list