Python Forum
A context to exit deeply nested loops
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
A context to exit deeply nested loops
#1
The break statement doesn't allow to exit several nested loops. It is a simple exercise to develop a block() context to do so. Here is an attempt
from contextlib import contextmanager

@contextmanager
def block():
    """Block of code context allowing to exit deeply nested loops
    
    Usage:
    
        with block() as b:
            ...
                    # somewhere in a nested loop
                    b.exit()
            ...
            
    """
    tok = BlockToken()
    try:
        yield tok
    except EndOfBlock as exc:
        if exc.args[0] is not tok:
            raise

class EndOfBlock(RuntimeError):
    """Helper exception type for the block() context"""

class BlockToken:
    """Helper class for block() context"""
    def exit(self):
        raise EndOfBlock(self)

def func(x):
    """Test function for the block() context"""
    result = ''
    with block() as outer:
        result += 'A'
        for i in range(4):
            result += 'B'
            if x > 0 and i > 2:
                outer.exit()
            result += 'D'
            with block() as inner:
                result += 'C'
                if x == 1:
                    outer.exit()
                elif x == 2:
                    inner.exit()
                result += 'E'
            result += 'F'
        result += 'G'
    result += 'H'
    return result

if __name__ == '__main__':
    assert func(0) == "ABDCEFBDCEFBDCEFBDCEFGH"
    assert func(1) == "ABDCH"
    assert func(2) == "ABDCFBDCFBDCFBH"
    print('SUCCESS')
An interesting feature here is that the BlockToken instance can be used as argument for functions called within the block. For example you could write
def do_something(session):
    if input('Do you want to quit?').strip().lower() in ('y', 'yes'):
        session.exit()
    for i in range(5):
        print(i)

with block() as user_session:
    do_something(user_session)
    print("If we're here, the user chose to stay!")
Reply


Messages In This Thread
A context to exit deeply nested loops - by Gribouillis - May-10-2019, 12:04 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Deeply nested JSON editing tool w/set arithmetic epieye 0 2,815 Sep-13-2021, 06:04 PM
Last Post: epieye

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020