0

Is there a way to stop the execution of the current indentation level? I'm looking for a way to break out of a block comparable to the break-statement in loops.

if some_state:
    if bool1:
        <jump to some-final-code> # Looking for this operator
    <some code>
    if bool2:
        <jump to some-final-code> # Looking for this operator
    <moa code>
elif some_other_state:
    <some_other_conditions_with_equally_possible_jumps>
<some_final_code>

I know that many ways exist to solve this in a readable way. Let's assume the code of the whole block is semantically related and should not be separated info different methods. Raising exceptions adds a lot of lines of code and another unwanted level of incomprehension.

MyNameIsFu
  • 90
  • 5
  • Python does not have a goto command. [Is there a label/goto in Python?](https://stackoverflow.com/q/438844/3890632) – khelwood Jul 23 '21 at 11:00
  • Have you try a `continue` ? – Rizquuula Jul 23 '21 at 11:00
  • 2
    Also note that "stop the execution of the current indentation level" would not help you: you're trying to stop execution of the indentation level above the current indentation level. – khelwood Jul 23 '21 at 11:05
  • @khelwood Being able to stop 1 indentation level implies the capability of stoping n-levels. Something like a goto statement would be perfect, but the docs refer to using exceptions instead. – MyNameIsFu Jul 23 '21 at 11:13
  • "Being able to stop 1 indentation level implies the capability of stoping n-levels."—No it doesn't. "the docs refer to using exceptions"—You specifically ruled out using exceptions in your question, so I'm not sure what your point is there. – khelwood Jul 23 '21 at 11:15
  • I'm looking for inspirations on 'how to produce readable code without bloating everything up with exceptions or nested conditions' – MyNameIsFu Jul 23 '21 at 11:20

2 Answers2

1

You could always invert the conditions, which would have the same effect if you don't mind more indentation levels:

if some_state:
    if not bool1:
        <some code>
        if not bool2:
            <moa code>
elif some_other_state:
    <some_other_conditions_with_equally_possible_jumps>
<some_final_code>

Alternatively, exceptions don't add many lines of code at all:

class GotoCleanup(Exception):
    pass

... whatever other code you have ...

try:
    if some_state:
        if bool1:
            raise GotoCleanup
        <some code>
        if bool2:
            raise GotoCleanup
        <moa code>
    elif some_other_state:
        <some_other_conditions_with_equally_possible_jumps>
finally:
    <some_final_code>

If you want to make sure you only catch your specific exception then you have to add a couple of extra lines:

try:
    if some_state:
        if bool1:
            raise GotoCleanup
        <some code>
        if bool2:
            raise GotoCleanup
        <moa code>
    elif some_other_state:
        <some_other_conditions_with_equally_possible_jumps>
except GotoCleanup:
    pass
finally:
    <some_final_code>

This will allow other exceptions to propogate as usual and would be considered best practice rather than swallowing all exceptions.

Kemp
  • 3,467
  • 1
  • 18
  • 27
  • I'm trying to avoid deep indentation levels. It's hard to keep track after more than 5 indentations which block started/continues/ends. Anyway a valid solution, thanks – MyNameIsFu Jul 23 '21 at 11:09
  • I've updated to include an exceptions example. You mentioned bloat with that, but it basically just adds two lines to your example. – Kemp Jul 23 '21 at 11:48
  • That alternative can actually become quite readable and powerful. Thanks very much :-) – MyNameIsFu Jul 23 '21 at 12:12
  • and in fact i forgot about the finally statement... – MyNameIsFu Jul 23 '21 at 12:12
0

How about encapsulating the behavior into a function? Then you can use return to end the execution of that function.

def myFunction():
    if some_state:
        if bool1:
            return
        <some code>
        if bool2:
            return
        <moa code>
    elif some_other_state:
        <some_other_conditions_with_equally_possible_jumps>

myFunction()
<some_final_code>

Taxel
  • 3,859
  • 1
  • 18
  • 40
  • That's what i'm currently doing, but i was wondering whether there might be a way to not split the logic across different methods. Still Thanks! – MyNameIsFu Jul 23 '21 at 11:11