spam = eggs if bar
# vs
spam = eggs if bar else None
spam = eggs if bar
# vs
spam = eggs if bar else None
x = func1() if something else func2()
In this example, only func1() or func2() is being called, but not both. x = if something:
func1()
else:
func2()
Would not work. At least that is what I imagine when it is said "make if an expression".Python is intended to enforce a strong distinction between statements and expressions (`:=` notwithstanding :/) because it sidesteps a lot of questions that one might otherwise ask about how it's intended to be parsed (including by humans).
Being able to write something like your example makes it harder to figure out where the end is, figure out what happens if there's more than one statement inside an `if` (do we only consider the result of the last expression? What if the last thing isn't an expression?), etc. By the time you get to the end of understanding what's happening inside the block, you can lose the context that the result is being assigned to `x`.
At the other extreme, everything is an expression, and you have Lisp with funky syntax. But Python holds that this syntactic structure is important for understanding the code. I sense that this is part of what "Flat is better than nested" is intended to mean.
We could have done that in the v3 switch, but we decided to spend man-centuries of effort on chasing already deprecated legacy Windows Unicode semantics instead.
(spam := eggs) if bar
I think that seems reasonable? It would act just the same as it already does with an explicit `else None`, if I'm not mistaken. I don't find it beautiful though.
I'm not advocating for this feature to be added to Python, just explaining why it's not confusing in Ruby.