[Python-ideas] Fwd: Null coalescing operator

Nick Coghlan ncoghlan at gmail.com
Tue Sep 13 07:37:48 EDT 2016


On 13 September 2016 at 21:15, Rob Cliffe <rob.cliffe at btinternet.com> wrote:
> On 13/09/2016 04:43, Guido van Rossum wrote:
>> Yeah, that's exactly my point. PEP 463 gives you a shorter way to
>> catch an exception, so it gives you less motivation to find a way to
>> write your code (or define your API) that doesn't involve catching
>> exceptions. But APIs involving exceptions are often inferior to APIs
>> that don't require exception catching. (Yes, I am aware of __next__()
>> raising StopIteration -- but that API design usually doesn't require
>> you to catch it.)
>>
> You surprise me.  I thought LBYL and EAFP were both approved Python idioms,
> in some cases one being better, in some cases another, choice to be made on
> the merits of each case (or the author's preference).  I certainly use both
> (and sometimes time both to see which is faster).
> Now it sounds as if you're trying to impose a style guide on the world by
> discouraging the EAFP.  And wasn't the discussion general, not about APIs
> specifically?

Which is preferable depends greatly on context of use, which is why
you'll find a lot of Python APIs offer both forms - it's not *just* a
matter of inheriting the exceptionless version from C, and then later
adding a Python version that gives an exception instead of None or a
user-supplied default value.

It's similar to why IEEE754 defines both quiet NaN *and* signalling
NaN - which one you want depends on what you're doing.

In web servers, for example, you'll often have lots of fields where
"not present" is a perfectly acceptable return value. For those, APIs
that just return None for unknown entries are very handy, which is why
SQL Alchemy offers both ".first()" and "one()", which mainly differ in
how and when they throw an exception, rather than what they do when
they succeed.

However, blindly catching *all* exceptions from a complex
subexpression is rarely the right thing to do, so APIs that only offer
"this may throw exceptions during normal operation under these
circumstances" without a convenience wrapper that does the exception
handling for you can end up being a pain to work with.

PEP 463 makes those APIs less painful to deal with, but at the cost of
encouraging overly broad exception handlers. By contrast, fixing APIs
on a case-by-case basis puts the design burden where it can do the
most good: on the API designer, who can make the scope of the
exception handling suitably narrow *inside* the API implementation,
rather than being limited to wrapping the entire API call in
try/except.

Cheers,
Nick.

P.S. There are also some use cases where Look-Before-You-Leap is
inherently subject to race conditions, and for those, exceptions are
the only reliable signaling mechanism.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-ideas mailing list