[Python-Dev] PEP 463: Exception-catching expressions

Steven D'Aprano steve at pearwood.info
Sat Feb 22 02:21:31 CET 2014


On Sat, Feb 22, 2014 at 01:15:13PM +1300, Greg Ewing wrote:
> Eli Bendersky wrote:
> >For instance, it is sometime non-trivial to know which exceptions some 
> >function may throw. When you write a try...raise statement, you think 
> >hard about covering all the bases. In an expression you're unlikely to,
> 
> Speak for yourself. I don't think I would put any less
> thought into which exception I caught with an except
> expression as I would for an except statement.

+1

With the possibly exception of messing about in the interactive 
interpreter, "catch as much as possible" is an anti-pattern. If you're 
not trying to catch as little as possible, you're doing it wrong.
 


> In fact, an except expression may even make it easier
> to catch exceptions in an appropriately targeted way.
> For example, a pattern frequently encountered is:
> 
>    result = computation(int(arg))
> 
> and you want to guard against arg not being a
> well-formed int. It's tempting to do this:
> 
>    try:
>       result = computation(int(arg))
>    except ValueError:
>       abort("Invalid int")
> 
> But that's bad, because the try clause encompasses
> too much. Doing it properly requires splitting up the
> expression:
> 
>    try:
>       i = int(arg)
>    except:
>       abort("Invalid int")
>    else:
>       result = computation(i)
> 
> With an except expression, it could be written:
> 
>    result = computation(int(arg)
>       except ValueError: abort("Invalid int"))

Nice example! Except I'd lay the code out a bit better to emphasise 
which part is being guarded:

    result = computation(
                 int(arg) except ValueError: abort("Invalid int")
                 )

Actually, not quite so nice as I first thought, since you're relying on 
the side-effects of abort() rather than returning a value. But apart 
from that quibble, the ability to guard *small* subcalculations without 
needing a visually heavy try...block is a good use-case.




-- 
Steven


More information about the Python-Dev mailing list