replacing `else` with `then` in `for` and `try`
Chris Angelico
rosuav at gmail.com
Fri Nov 3 12:24:42 EDT 2017
On Sat, Nov 4, 2017 at 3:15 AM, Alexey Muranov <alexey.muranov at gmail.com> wrote:
> On Fri, 2017-11-03 at 22:03 +1100, Chris Angelico wrote:
>> On Fri, Nov 3, 2017 at 8:48 PM, Alexey Muranov <alexey.muranov at gmail.
>> com> wrote:
>> > 'Then' describes what happens next indeed, unless some
>> > extraordinary
>> > situation prevents it from happening, for example:
>> >
>> > try:
>> > go_to_the_bakery()
>> > then:
>> > buy_croissants(2)
>> > except BakeryClosed:
>> > go_to_the_grociery()
>> > buy_baguette(1)
>> > finally:
>> > come_back()
>> >
>> > I know this is a poor program example (why not to use a boolean
>> > return value
>> > instead of an exception, etc.), and i know that currently in Python
>> > `except`
>> > must precede `else`, it is just to illustrate the choice of terms.
>>
>> What is the semantic difference between that code and the same
>> without the "then:"?
>
> Chris,
>
> the semantic difference is that their meanings/behaviours are not identical
> (i imply that `then` here does what `else` currently does). I agree however
> that from practical viewpoint the difference will probably never be
> observable (unless the person enters the bakery and asks for croissants, but
> during this time the baker exits the bakery and closes it to go on
> vacation).
Okay, so what you're doing is taking the current "try/else" semantics,
and hoisting the "happy path" up to immediately underneath the part
guarded by the try. That's not unreasonable, but also not a huge
advantage. It's basically saying:
try:
do_stuff
except None: # let's pretend
print("all is well")
except ValueError:
print("do_stuff has the wrong value")
finally:
print("we're done")
But if the difference between this and the current layout (with "else"
coming *after* the except blocks) is significant to you, I would
recommend refactoring the try/finally into a context manager:
with car_trip() as trip:
try:
trip.goto(bakery)
buy_croissants(2)
except BakeryClosed:
trip.goto(grocery)
buy_baguette(1)
The context manager takes care of bringing us home unconditionally,
leaving us with cleaner logic.
ChrisA
More information about the Python-list
mailing list