Confused compare function :)

Chris Angelico rosuav at gmail.com
Thu Dec 6 08:58:01 EST 2012


On Fri, Dec 7, 2012 at 12:33 AM, Thomas Rachel
<nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915 at spamschutz.glglgl.de>
wrote:
> Am 06.12.2012 09:49 schrieb Bruno Dupuis:
>
>> The point is Exceptions are made for error handling, not for normal
>> workflow. I hate when i read that for example:
>>
>>      try:
>>          do_stuff(mydict[k])
>>      except KeyError:
>>          pass
>
> I would do
>
>     try:
>         value = mydict[k]
>     except KeyError:
>         pass
>     else:
>         do_stuff(k)
>
> Why? Because do_stuff() might raise a KeyError, which should not go
> undetected.

(Assuming first off that you meant "do_stuff(value)", not
"do_stuff(k)", in that last line)

That has quite different functionality, though. The original wouldn't
have called do_stuff at all if k is not in dict, behaviour which is
matched by both his EAFP and his LBLY. But your version, in the event
of a KeyError, will call do_stuff with the previous value of value, or
raise NameError if there is no such previous value. I don't think
that's intentional.

The only way around it that I can see is an extra condition or jump -
something like:

def call_if_present(mydict,k,do_stuff):
    """Equivalent to
    do_stuff(mydict[k])
    if the key is present; otherwise, does not call do_stuff, and
returns None."""
    try:
        value = mydict[k]
    except KeyError:
        return
    return do_stuff(value)

It'll propagate any other exceptions from the subscripting (eg
TypeError if you give it a list instead of a dict), and any exceptions
from do_stuff itself. But it's getting a bit unwieldy.

ChrisA



More information about the Python-list mailing list