[Python-Dev] PEP 340: Deterministic Finalisation (new PEP draft, either a competitor or update to PEP 340)

Ron Adam rrr at ronadam.com
Mon May 9 03:54:44 CEST 2005


Josiah Carlson wrote:

> Ron Adam <rrr at ronadam.com> wrote:

>>I should have said  "...should not finalize at the end of the for loop". 
>>  With generators, you may not want them to finalize before you are done 
>>with them, and the same with class's.
> 
> 
> So you don't use them with a structure that greedily finalizes, and you
> keep a reference to the object exterior to the loop.  Seems to be a
> non-issue.

Yes, it should be a non issue.


> The argument over whether blocks should loop, I believe has been had;
> they should.  The various use cases involve multi-part transactions and
> such.

I think so now too, I had thought as Nick does earlier this week that 
the non-looping version was cleaner, but changed my mind when I realized 
that looping blocks could be made to work for those in a simple and 
understandable way.

>>try:
>>     for x in range(100):
>>         for y in range(100):
>>             for z in range(100):
>>             	if x == 25 and y==72 and z==3:
>>                     raise BreakLoop
>>
>>except BreakLoop: pass
>>print 'x,y,z =', x,y,z

> That is a mechanism, but I like it even less than the one I offered. 
> Every time that one wants ot offer themselves the ability to break out
> of a different loop (no continue here), one must create another
> try/except clause, further indenting, and causing nontrivial try/except
> overhead inside nested loops.
> 
> A real solution to the problem should (in my opinion) allow the breaking
> of or continuing to an arbitrary for/while/block.  Humorously enough,
> Richie Hindle's goto/comefrom statements for Python ("not to be used in
> production code") would allow 90% of the necessary behavior (though the
> lack of timely finalization would probably annoy some people, but then
> again, there is only so much one can expect from a module written as a
> working April Fools joke over a year ago).
> 
>  - Josiah

I think maybe another alternative is a break buffer or cue. Where you 
push a 'break' onto the buffer and then execute a 'break' to break the 
current loop, The 'break' in the buffer then breaks the next loop out as 
soon as the current loop exits, etc.

for x in range(100):
     for y in range(100):
         for z in range(100):
            if x == 25 and y==72 and z==3:
               push_loop(Break,Break)  # will break both parent loops
               break                   # break current loop

if push_loop(...) could take a NoBreak, then you can selectively break 
outer breaks by how you sequence them.

push_break(None, break) wound not break the y loop, but will break the x 
loop above.  Can you think of a use case for something like that?


Pushing 'Continues' might also work:

for x in range(100):
     for y in range(100):
         if x == 25 and y==72:
             push_loop(Continue)  # will skip rest of parents body
             break                # break current loop
         #code2
     #code1

This will break the 'y' loop and skip code2, then continue the 'x' loop 
skipping code block 1.

Using a stack for breaks and continues isn't too different than using a 
stack for exceptions I think.

Also by making it a function call instead of a command you can have a 
function return a Break or Continue object, or None,

for x in range(100):
    for y in range(100):
       if y == testval:
           push_loop(looptest(x,y)):    break x loop depending on x,y
           break

None's returned would need to be discarded I think for this to work, so 
something else would be needed to skip a level.

It needs some polish I think.  ;-)

Cheers,
Ron_Adam




More information about the Python-Dev mailing list