On Mon, Dec 7, 2020 at 6:27 PM Daniel Moisset <[email protected]> wrote:
> For the likely rare situation where I'd want to do this rather than > refactoring into a function, I might try with something like this without > requiring changes to the language: > > from contextlib import contextmanager > > @contextmanager > def breakable(): > class Break(Exception): pass > def breaker(): raise Break > try: > yield breaker > except Break: > pass > > This allows defining a block that can be "aborted" (which can have a loop > or any other statement block within); you abort it by calling the resulting > value of the context manager. An example of use is available at > https://gist.github.com/dmoisset/55f5916f9f339a143b6f3d155de8706e > > I agree with the person who called this a brilliant solution. Here is the code from the link for completeness: for outer in range(5): with breakable() as brk: for middle in range(5): for inner in range(10): print(outer, middle, inner) if middle == 1 and inner == 5: brk() print(f"end middle loop #{middle}") print(f"end outer loop #{outer}") print("done") Iterating on that idea a bit and taking advantage of the walrus, what if syntax were created allowing us to remove the extra indentation level, and also allowing us to contextualize any loop without having to employ the with statement? I imagine is looking something like this: for outer in range(5): @breakable for middle in loopX := range(5): for inner in range(10): print(outer, middle, inner) if middle == 1 and inner == 5: loopX.brk() print(f"end middle loop #{middle}") print(f"end outer loop #{outer}") print("done") Above, breakable will be some decorator that returns a context manager, and the "loopX" loop happens in the context of that context manager (with the name "loopX" assigned to the context object). Here is some more detail about what I am imagining happening with this new syntax: 1. the name `loopX` is assigned to the iterable in the for statement, as usual 2. the first time the for statement ` for middle in loopX := range(5): ` is interpreted/excuted, the presence of the decorator causes this to happen before iteration starts: loopX = breakable(loopX) with loopX as loopX: for middle in loopX := range(5): # the "loopX" loop is now executed within the loopX context 3. the utility of this syntax would not be limited to the breaking of named loops. with this syntax in place, one could write any kind of context manager they want for contextualizing the execution of loops (both for loops and while loops). 4. last note: if no name is supplied to the iterable object using the walrus, then applying the decorator to the loop would be a syntax error What do you think? --- Ricky. "I've never met a Kentucky man who wasn't either thinking about going home or actually going home." - Happy Chandler <http://python.org/psf/codeofconduct/> >
_______________________________________________ Python-ideas mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/[email protected]/message/BQCGXITAKOVG24KWYZB5CW7DUFFYM3AK/ Code of Conduct: http://python.org/psf/codeofconduct/
