I've taken the liberty of adding the following old but good rule to PEP 8 (I was surprised to find it wasn't already there since I've lived by this for ages): - Be consistent in return statements. Either all return statements in a function should return an expression, or none of them should. If any return statement returns an expression, any return statements where no value is returned should explicitly state this as return None, and an explicit return statement should be present at the end of the function (if reachable). Yes: def foo(x): if x >= 0: return math.sqrt(x) else: return None def bar(x): if x < 0: return None return math.sqrt(x) No: def foo(x): if x >= 0: return math.sqrt(x) def bar(x): if x < 0: return return math.sqrt(x) -- --Guido van Rossum (python.org/~guido)
On Apr 06, 2015, at 06:08 PM, Guido van Rossum wrote:
I've taken the liberty of adding the following old but good rule to PEP 8 (I was surprised to find it wasn't already there since I've lived by this for ages):
Be consistent in return statements. Either all return statements in a function should return an expression, or none of them should. If any return statement returns an expression, any return statements where no value is returned should explicitly state this as return None, and an explicit return statement should be present at the end of the function (if reachable).
+1 Odd synchronicity: Today I discovered an old interface that was documented as returning a "thing or None" but the latter was relying on implicit None return in some cases. Fixed of course in exactly the way PEP 8 now recommends. :) Cheers, -Barry
On 07/04/2015 02:08, Guido van Rossum wrote:
I've taken the liberty of adding the following old but good rule to PEP 8 (I was surprised to find it wasn't already there since I've lived by this for ages):
*
Be consistent in return statements. Either all return statements in a function should return an expression, or none of them should. If any return statement returns an expression, any return statements where no value is returned should explicitly state this asreturn None, and an explicit return statement should be present at the end of the function (if reachable).
Yes:
def foo(x): if x >= 0: return math.sqrt(x) else: return None
That would seem to be good style and common sense. As a matter of interest, how far away from mainstream am I in preferring, *in this particular example* (obviously it might be different for more complicated computation), def foo(x): return math.sqrt(x) if x >= 0 else None I probably have a personal bias towards compact code, but it does seem to me that the latter says exactly what it means, no more and no less, and therefore is somewhat more readable. (Easier to keep the reader's attention for 32 non-whitespace characters than 40.) Sorry if this is irrelevant to Guido's point. Rob Cliffe
On Tue, Apr 07, 2015 at 03:11:30AM +0100, Rob Cliffe wrote:
As a matter of interest, how far away from mainstream am I in preferring, *in this particular example* (obviously it might be different for more complicated computation),
def foo(x): return math.sqrt(x) if x >= 0 else None
I probably have a personal bias towards compact code, but it does seem to me that the latter says exactly what it means, no more and no less, and therefore is somewhat more readable. (Easier to keep the reader's attention for 32 non-whitespace characters than 40.)
In my opinion, code like that is a good example of why the ternary if operator was resisted for so long :-) Sometimes you can have code which is just too compact. My own preference would be: def foo(x): if x >= 0: return math.sqrt(x) return None but I'm not terribly fussed about whether the "else" is added or not, whether the return is on the same line as the if, and other minor variations. -- Steve
My own preference would be:
def foo(x): if x >= 0: return math.sqrt(x) return None
Kind of getting into the weeds here, but I would always invert this to "return errors early, and keep the normal flow at the main indentation level". Depends a little on what foo() means, but it seems to me the "return None" case is the exceptional/error case, so this would be: def foo(x): if x < 0: return None return math.sqrt(x) The handling of errors is done first, and the normal case stays at the main indentation level. Is this discussed in style guides at all? I don't see anything directly in PEP 8, but I might be missing something. Oh wait, I just noticed this is exactly how Guido has it in his PEP addition with the definition of bar(). :-| -Ben
On Tue, Apr 07, 2015 at 08:47:25AM -0400, Ben Hoyt wrote:
My own preference would be:
def foo(x): if x >= 0: return math.sqrt(x) return None
Kind of getting into the weeds here, but I would always invert this to "return errors early, and keep the normal flow at the main indentation level". Depends a little on what foo() means, but it seems to me the "return None" case is the exceptional/error case, so this would be:
def foo(x): if x < 0: return None return math.sqrt(x)
While *in general* I agree with "handle the error case early", there are cases where "handle the normal case early" is better, and I think that this is one of them. Also, inverting the comparison isn't appropriate, due to float NANs. With the first version, foo(NAN) returns None (which I assumed was deliberate by the OP). In your version, it returns NAN. But as you say, we're now deep into the weeds... -- Steve
On Tue, 07 Apr 2015 03:11:30 +0100
Rob Cliffe
On 07/04/2015 02:08, Guido van Rossum wrote:
I've taken the liberty of adding the following old but good rule to PEP 8 (I was surprised to find it wasn't already there since I've lived by this for ages):
*
Be consistent in return statements. Either all return statements in a function should return an expression, or none of them should. If any return statement returns an expression, any return statements where no value is returned should explicitly state this asreturn None, and an explicit return statement should be present at the end of the function (if reachable).
Yes:
def foo(x): if x >= 0: return math.sqrt(x) else: return None
That would seem to be good style and common sense.
As a matter of interest, how far away from mainstream am I in preferring, *in this particular example* (obviously it might be different for more complicated computation),
def foo(x): return math.sqrt(x) if x >= 0 else None
I agree with you on this. Regards Antoine.
Antoine Pitrou schrieb am 07.04.2015 um 14:26:
On Tue, 07 Apr 2015 03:11:30 +0100 Rob Cliffe
wrote: On 07/04/2015 02:08, Guido van Rossum wrote:
I've taken the liberty of adding the following old but good rule to PEP 8 (I was surprised to find it wasn't already there since I've lived by this for ages):
*
Be consistent in return statements. Either all return statements in a function should return an expression, or none of them should. If any return statement returns an expression, any return statements where no value is returned should explicitly state this asreturn None, and an explicit return statement should be present at the end of the function (if reachable).
Yes:
def foo(x): if x >= 0: return math.sqrt(x) else: return None
That would seem to be good style and common sense.
As a matter of interest, how far away from mainstream am I in preferring, *in this particular example* (obviously it might be different for more complicated computation),
def foo(x): return math.sqrt(x) if x >= 0 else None
I agree with you on this.
+1, the ternary operator reads best when there is a "normal" case that can go first and a "special" or "unusual" case that can go last and does not apply under the (given) normal conditions. Stefan
Talk about hijacking an unrelated thread... :-(
Though there's maybe a style rule for the ternary operator to be devised
here? :-)
On Apr 7, 2015 11:36 AM, "Stefan Behnel"
Antoine Pitrou schrieb am 07.04.2015 um 14:26:
On Tue, 07 Apr 2015 03:11:30 +0100 Rob Cliffe
wrote: On 07/04/2015 02:08, Guido van Rossum wrote:
I've taken the liberty of adding the following old but good rule to PEP 8 (I was surprised to find it wasn't already there since I've lived by this for ages):
*
Be consistent in return statements. Either all return statements in a function should return an expression, or none of them should. If any return statement returns an expression, any return statements where no value is returned should explicitly state this asreturn None, and an explicit return statement should be present at the end of the function (if reachable).
Yes:
def foo(x): if x >= 0: return math.sqrt(x) else: return None
That would seem to be good style and common sense.
As a matter of interest, how far away from mainstream am I in preferring, *in this particular example* (obviously it might be different for more complicated computation),
def foo(x): return math.sqrt(x) if x >= 0 else None
I agree with you on this.
+1, the ternary operator reads best when there is a "normal" case that can go first and a "special" or "unusual" case that can go last and does not apply under the (given) normal conditions.
Stefan
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/guido%40python.org
participants (7)
-
Antoine Pitrou
-
Barry Warsaw
-
Ben Hoyt
-
Guido van Rossum
-
Rob Cliffe
-
Stefan Behnel
-
Steven D'Aprano