[Python-ideas] except expression
M.-A. Lemburg
mal at egenix.com
Thu Feb 20 16:22:27 CET 2014
On 20.02.2014 15:46, Rob Cliffe wrote:
>
> On 20/02/2014 13:45, M.-A. Lemburg wrote:
>> On 20.02.2014 02:18, Chris Angelico wrote:
>>> On Thu, Feb 20, 2014 at 11:15 AM, Ethan Furman <ethan at stoneleaf.us> wrote:
>>>> result = 1/x except ZeroDivisionError -> NaN
>>>>
>>>> For the record, I could just as easily live with the colon instead of the
>>>> arrow.
>>>>
>>> Time to open up this branch of the discussion... colon or arrow?
>>>
>>> For the purposes of this debate, I'm comparing these two notations,
>>> and nothing else:
>>>
>>> result = 1/x except ZeroDivisionError -> NaN
>>> result = 1/x except ZeroDivisionError: NaN
>> I'm -1 on both of them.
> I'm afraid answering your post will mean repeating stuff said earlier in this thread, but here goes:
>> The colon should stay reserved for starting new blocks of statements.
> It isn't reserved for that - it is already used for slices, dictionary literals and lambdas.
>> The arrow is used for return type annotations, which is a completely
>> different concept than returning values.
> (I'm not so keen on the arrow myself but) with a limited set of characters, some of them have to
> perform more than one role, as colons, dots, parentheses and braces (to name but a few) already do.
>>
>> I also find it disturbing that people are actually considering
>> to use this expression form as a way to do quick&dirty suppression
>> of exceptions.
> This is a relatively common construction (as a survey of my own small codebase indicates). Quick,
> yes. How dirty it is depends entirely on context, (and how readable it can be made) and is up to
> the programmer's judgment.
>>
>> The intended use case should really be limited to providing default
>> values for functions or methods that are expected to return a value.
> That's your opinion. Why, if it is useful in other ways? [1]
Sure, it's my opinion :-) That's what this mailing list is all about:
tossing around ideas.
As I've mentioned before, I think people are putting too many
features into this expression style and just want to express this
concern.
The thread started out with the objective to find a solution for
the common default argument problem - which is a good thing.
The current discussion is getting somewhat out of focus.
>> Abusing the fact that procedures in Python return None (simply
>> because we don't have procedures and need to use functions instead)
>> to make use of except expressions would make code less readable.
> I don't quite see the relevance. None of your examples rely on a function returning None. Could
> you give an example?
I gave an example below and Nick gave another one.
>> x = data[1] except IndexError return None # is readable
> Agreed.
>> f = open('x.txt', 'r') except IOError return None # is probably not a good idea
> I personally think this could be spelt more readably (with a colon or "then"). But however it's
> done, it's a meaningful and useful construct.
I usually consider an IOError to be too serious to hide away in a
single line.
>> os.remove('/') except IOError return None # is really bad style
> Do you mean because it's not very readable (I agree) or because it's necessarily a bad thing to do
> (I disagree, particularly if we chose a less drastic example)?
The above is the procedure example I was talking about above.
I find this an even worse style than the open() error, since
there's absolutely no need to use an expression for this - the
os.remove() will never return a value, so you don't need
an expression.
>> The purpose of such except expressions should be to work around
>> small corner cases, not to address important exceptional cases
>> in ones applications.
> See [1] above.
>>
>>
>> Sometimes I wish we had expression objects in Python to wrap
>> expressions without evaluating them - sort of like lambdas
>> without arguments but with a nicer syntax. These could then
>> be used to implement a default() builtin.
>>
>> Here's a version using lambdas as example:
>>
>> def default(expr, value=None, *exceptions):
>> try:
>> expr()
>> except exceptions:
>> return value
>>
>> x = default(lambda: 1/0, None, ZeroDivisionError)
>>
>> print (x)
>>
> This is interesting. Expression objects might be useful in various ways. But it seems a rather
> circuitous and obscure way to provide a default value after an exception, and harder to extend:
> x = default(lambda: d1[key], default(lambda:d2[key], None, KeyError), KeyError) # And I hope I've
> spelt it right!
Well, like I said: the lambda notation doesn't make this look very
nice, but the builtin function approach certainly is a lot more flexible
than having to introduce a new syntax.
BTW: The indexing example that started this thread is so common that
I put a special function into mxTools to address it (back in 1998):
get(object,index[,default])
Returns object[index], or, if that fails, default.
and this works for all indexing compatible objects.
You can find more such tools here:
http://www.egenix.com/products/python/mxBase/mxTools/
(a lot of those things are no longer needed, since Python has grown
built-in support for them over the years)
--
Marc-Andre Lemburg
eGenix.com
Professional Python Services directly from the Source (#1, Feb 20 2014)
>>> Python Projects, Consulting and Support ... http://www.egenix.com/
>>> mxODBC.Zope/Plone.Database.Adapter ... http://zope.egenix.com/
>>> mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
________________________________________________________________________
2014-02-12: Released mxODBC.Connect 2.0.4 ... http://egenix.com/go53
::::: Try our mxODBC.Connect Python Database Interface for free ! ::::::
eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48
D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
Registered at Amtsgericht Duesseldorf: HRB 46611
http://www.egenix.com/company/contact/
More information about the Python-ideas
mailing list