[Python-ideas] if expensive_computation() as x:
Steven D'Aprano
steve at pearwood.info
Fri Feb 14 21:38:14 CET 2014
On Fri, Feb 14, 2014 at 07:49:02AM +0100, Michele Lacchia wrote:
> You could gather all the functions in a list and then iterate and break
> when needed:
>
> for func in [f1, f2, f3, f4]:
> x = func()
> if x:
> # bla bla
> break
To me, that is the cleanest, most obvious solution to avoid repeating
yourself. Must nicer than the suggestion to add name binding to
arbitrary expressions.
The only downside is that it assumes the "bla bla" part is identical for
each function.
Coming back to Ram's suggestion:
> > if expensive_computation_0():
> > x = expensive_computation_0()
> > # Do something with x...
> > elif expensive_computation_1():
> > x = expensive_computation_1()
> > # Do something with x...
> > elif expensive_computation_2():
> > x = expensive_computation_2()
> > # Do something with x...
> >
> > The problem here is that we're doing the expensive computation twice.
It's not really a language problem. The problem is not the lack of
syntax, but the poor way the code is written, avoiding taking advantage
of Python's already existing features. Put the code inside a function,
assign the expensive computations once each time, and return as needed:
def perform_expensive_calculation():
x = expensive_computation_0()
if x:
# Do something with x...
return
x = expensive_computation_1()
if x:
# Do something with x...
return
This requires no new syntax, and it is easy to understand. If the "do
something" parts include returning a value, you can drop the bare
returns as well.
> > Obviously this can be "solved", i.e. rewritten in a way that wouldn't call
> > the expensive operation twice, but the solution would probably be quite
> > verbose, which is something we don't want.
It's not at all verbose. Apart from the extra returns, which are only
needed if you're not otherwise returning from the "do something" parts,
it is no more verbose than what you already have.
> > My suggestion:
> >
> > if expensive_computation_0() as x:
> > # Do something with x...
If we must have an alternative name binding of expressions, I don't mind
this too much. But I'm not sold that this is needed.
> > If you'd like to bind to a variable only a part of the condition, this
> > would work too:
> >
> > if x<5 with expensive_computation_0() as x:
> > # Do something with x
I think that's hard to understand, unnecessary and clashes with the
existing use of "with". It also leads to the possibility of abuse:
x < 5 with (y + 1)/y with z*(z+1) with function(arg) as z as y as x
--
Steven
More information about the Python-ideas
mailing list