Good python equivalent to C goto

Matthew Fitzgibbons elessar at nienna.org
Sun Aug 17 21:23:08 CEST 2008


info at orlans-amo.be wrote:
> On Aug 17, 8:09 pm, Matthew Fitzgibbons <eles... at nienna.org> wrote:
>> Kurien Mathew wrote:
>>> Hello,
>>> Any suggestions on a good python equivalent for the following C code:
>>> while (loopCondition)
>>> {
>>>     if (condition1)
>>>         goto next;
>>>     if (condition2)
>>>         goto next;
>>>     if (condition3)
>>>         goto next;
>>>     stmt1;
>>>     stmt2;
>>> next:
>>>     stmt3;
>>>     stmt4;
>>>  }
>>> Thanks
>>> Kurien
>>> --
>>> http://mail.python.org/mailman/listinfo/python-list
>> I would not be too happy if I saw C code like that in my repository.
>> This is equivalent:
>>
>> while (loopCondition) {
>>      if (!(condition1 || condition2 || condition3)) {
>>          stmt1;
>>          stmt2;
>>      }
>>      stmt3;
>>      stmt4;
>>
>> }
>>
>> In Python:
>>
>> while (loopCondition):
>>      if not (condition1 or condition2 or condition3):
>>          stmt1
>>          stmt2
>>      stmt3
>>      stmt4
>>
>> If stmt3 and stmt4 are error cleanup code, I would use try/finally.
>>
>> while loopCondition:
>>      try:
>>          if condition1:
>>              raise Error1()
>>          if condition2:
>>              raise Error2()
>>          if condition3:
>>              raise Error3()
>>          stmt1
>>          stmt2
>>      finally:
>>          stmt3
>>          stmt4
>>
>> This will also bail out of the loop on and exception and the exception
>> will get to the next level. If you don't want that to happen, put an
>> appropriate except block before the finally.
>>
>> -Matt- Hide quoted text -
>>
>> - Show quoted text -
> 
> class Goto_Target(Exception):
>     pass
> 
> def Goto_is_not_dead(nIn):
>     try:
>         if (nIn == 1): raise Goto_Target
>         if (nIn == 2): raise Goto_Target
> 
>         inv = 1.0 / nIn
>         print 'Good Input ' + str(nIn) + ' inv=' + str(inv)
> 
>     except Goto_Target:
>         pass
>     except Exception, e:
>         print 'Error Input ' + str(nIn) + ' ' + str(e)
>     finally:
>         print 'any input ' + str(nIn)
> 
> if __name__ == '__main__':
>     Goto_is_not_dead(0)
>     Goto_is_not_dead(2)
>     Goto_is_not_dead(3)
> --
> http://mail.python.org/mailman/listinfo/python-list
> 

I think this is needlessly ugly. You can accomplish the same with a 
simple if-else. In this case you're also masking exceptions other than 
Goto_Target, which makes debugging _really_ difficult. If you need to 
have the cleanup code executed on _any_ exception, you can still use 
try-finally without any except blocks. Your code is equivalent to this:

def goto_is_dead(n):
     try:
         if n == 0 or n == 1 or n == 2:
             # if you're validating input, validate the input
             print "Error Input %s" % n
         else:
             print "Good Input %s inv= %s" % (n, (1. / n))
     finally:
         print "any input %s" % n

if __name__ == '__main__':
     goto_id_dead(0)
     goto_id_dead(2)
     goto_id_dead(3)

More concise, readable, and maintainable.

-Matt



More information about the Python-list mailing list