[Python-ideas] except expression

Andrew Barnert abarnert at yahoo.com
Thu Feb 13 02:52:36 CET 2014


From: Ben Finney <ben+python at benfinney.id.au>

Sent: Wednesday, February 12, 2014 4:28 PM


> Subject: Re: [Python-ideas] except expression
> 
> Ben Finney <ben+python at benfinney.id.au> writes:
> 
>>  Ram Rachum <ram.rachum at gmail.com> writes:
>> 
>>  > Here's an idea that would help shortening code. Allow a ternary
>>  > expression based on except, like so:
>>  >
>>  >     first_entry = entries[0] except IndexError else None
>>  >     item = my_queue.get() except queue.Empty else None
>>  >     response_text = request('http://whatever.com').text except 
> HttpError else "Can't access data"
>> 
>>  That is more obscure, to my eye, than laying out the control branches:
> 
> Sorry, I failed to address your first two examples.
> 
> I am +0 on the proposal to have something similar to Perl's fallback
> syntax, “$foo = bar() or some_default_value”.

Although this looks nicer than the original proposal, it loses the ability to specify what exception you want to catch. And I think it would be reasonable to want to, e.g., handle queue.Empty but not swallow an AttributeError caused by a typo… On the other hand, I really dislike the misuse of else in the original version. But the syntax can be bikeshedded, and probably has been before.

I have one reservation: Given that so many functions in Python take a "default value" parameter, could this lead to making the language less predictable and consistent? For some expressions, you write "d.get(key, defval)", while for others you write "d.get(key) except KeyError else defval", and it may not be obvious which are which. And I don't think the answer is to remove all those default values. The d.get(key, defval) is much more concise and a bit more readable, and removes the opportunity to, e.g., screw up and use the wrong exception type.

But other than that, if someone can come up with a readable way to write it, I like the idea.

> Yet I still find the proposed syntax less readable for anything but a
> trivial *and* brief case.

I agree—but the same is true for pretty much all expression syntax, and most of it is rarely misused.

Consider if-else ternary expressions. It's very easy to make your code completely unreadable by chaining them together, or using complex test expressions, or using them in the middle of a comprehension, etc. But you rarely see such code. And meanwhile, you see a lot of code that's more concise and readable because it uses trivial if expressions. I think that except expressions would go the same way.

> For anything longer than a few dozen

> characters, I still prefer::
> 
>     try:
>         response_text = request('http://whatever.com').text
>     except HttpError:
>         "Can't access data"
> 
> for being explicit and clarifying what to expect.


Except that you're not doing the same thing as the original; you're just evaluating and throwing away the string literal, and not assigning anything to response_text. Having to write "response_text = " twice gives you twice as many places to screw up—as evidenced by the fact that you did so. The exact same thing happens with if statements vs. if expressions, and in fact I think that's one of the reasons people like if expressions.


More information about the Python-ideas mailing list