Try, except...retry?

Robert Brewer fumanchu at amor.org
Fri Nov 14 07:58:29 CET 2003


Alex Martelli wrote:
> In retrospect, it WOULD perhaps be better if setdefault was designed
> to take a callable (and optional args for it) and only call it if and
> when needed -- that would add a little speed and clarity
>
> Yes, flags (hiding control flow in data!) and repeated code 
> do suck, but
> you need neither to get exactly the same semantics as your 
> desideratum:
> 
>     while True:
>         try: allPiranhas['Doug'].weapon = u'satire'
>         except KeyError: allPiranhas['Doug'] = Pirhana()
>         else: break
> 
> I could be wrong, of course: there is nothing that appears to me
> to be "outrageously nonPythonic" in your proposal -- it just seems
> that new statements need to be more of a win than this in order to
> stand a chance.  But a PEP on this is surely warranted, if you want
> to try one.
> 
> No special "implications", as the semantics are just about the
> same as the above-indicated (flags-less, duplication-less)
> "while True:" loop that is so easy to code explicitly today.
> 
> It's just that, partly because of this (and attendant benefits
> that writing out "while" DOES clearly indicate to the reader
> that the following code may repeat, etc etc), it does not seem
> to me that 'retry' is worth adding.  But unless somebody does
> write a PEP, you'll just have my opinion about this...

Agreed. I'm new enough I'm still easy to convince. :) On a lark, I
decided to dump the bytecodes and see what I could see. It comes out, in
my math, to about 20 bytecodes saved using "retry" instead of "while
True", mostly due to saving the nested block. See the lines I've marked
with a * below, which I think would be taken out if we had retry. I'm
not a master of Python, I assume the left column in dis.dis() output
increments by more than one to mean that instruction takes more cycles.
I also assume byte 60 would have to be replaced with a JUMP_ABSOLUTE to
SETUP_EXCEPT. It depends on whether SETUP_EXCEPT would have to be
reexecuted again--does it? Anyone?

>>> def loop():
... 	while True:
... 		try:
... 			print a
... 		except:
... 			a = 0
... 		else:
... 			break
... 		
>>> loop()
0
>>> dis.dis(loop)
          0 SET_LINENO               1

*         3 SET_LINENO               2
*         6 SETUP_LOOP              56 (to 65)

*   >>    9 SET_LINENO               2
*        12 LOAD_GLOBAL              0 (True)
*        15 JUMP_IF_FALSE           45 (to 63)
*        18 POP_TOP             

         19 SET_LINENO               3
         22 SETUP_EXCEPT            12 (to 37)

         25 SET_LINENO               4
         28 LOAD_FAST                0 (a)
         31 PRINT_ITEM          
         32 PRINT_NEWLINE       
         33 POP_BLOCK           
         34 JUMP_FORWARD            19 (to 56)

    >>   37 SET_LINENO               5
         40 POP_TOP             
         41 POP_TOP             
         42 POP_TOP             

         43 SET_LINENO               6
         46 LOAD_CONST               1 (0)
         49 STORE_FAST               0 (a)
         52 JUMP_FORWARD             5 (to 60)
         55 END_FINALLY         

*   >>   56 SET_LINENO               8
*        59 BREAK_LOOP          
*   >>   60 JUMP_ABSOLUTE            9
    >>   63 POP_TOP             
         64 POP_BLOCK           
    >>   65 LOAD_CONST               0 (None)
         68 RETURN_VALUE        


Robert Brewer
MIS
Amor Ministries
fumanchu at amor.org





More information about the Python-list mailing list