In Python it's possible to create a procedure that has no explicit return. i.e.:
def test(val):
if 0 == val:
return 8
Further, it's possible to assign the results of that function to a variable:
>>> a = test(7)
>>> print `a`
'None'
Why the heck is that? What language logic is behind that baffling design decision? Why doesn't that simply raise a compiler error?
EDIT: Yes, I realise that it works that way. Thanks. My question is WHY? It seems like such a sure fire way to introduce subtle bugs into your code. And it seems, as was mentioned below by e-satis, to go against the very wise pythonic adage that "explicit is better then implicit".
So, what's up with this? Is it just a design oversight or a simplifying assumption or a deliberate, considered decision?
EDIT: Would everyone agree that expressing the intent this way is much better:
def test(val):
if 0 == val:
return 8
else:
return None
If so, why would Python prefer the former style to raising a compile time exception?
EDIT: S.Lott brings up the point explicitly (and others do too, his just seems most clear to me) that this behaviour is a result of the fact that Python is a dynamic language and therefor can't check at compile time, the run time behaviour of the system.
Since there is no distinction between procedures (those functions that return no values) and functions (those that do), that there is nothing to enforce at compile time. Which means that when we come to run-time behaviour, we either have a catastrophic failure in some cases (we throw an exception) or we silently fail assuming that the programmer knew what they were doing and understood the default behaviour.
The pythonic way is to do the latter, the C-style way is to do the former.
That seems to make sense as a good reason to do it that way.
S.Lott's clear justification is buried in the comments to the accepted answer so I thought it best to summarise here.
I'll hold off on accepting the answer for a bit to see if S.Lott makes an official answer. Otherwise, I'll give the points to SilentGhost.
A Python function will always have a return value. There is no notion of procedure or routine in Python. So, if you don't explicitly use a return value in a return statement, or if you totally omit the return statement, then Python will implicitly return a default value for you.
1 Answer. To Ignore python multiple return value you can use the "_" as a variable name for the elements of the tuple.
A return statement effectively ends a function; that is, when the Python interpreter executes a function's instructions and reaches the return , it will exit the function at that point.
While every function might not have an explicit return it will have an implicit one, that is None
, which incidentally is a normal Python object. Further, functions often return None
explicitly.
I suppose returning None implicitly is just an ease-of-use optimisation.
P.S. I wonder what you propose compile would do in the following case:
def t():
if True:
return 'ham'
P.P.S. return
statement indicates that something needs to be returned, be it None
, 42
or 'spam'
. Some functions, however, don't really return anything, like list.sort
or __init__
, therefore it would be an overhead to require a return None
statement at the end of each __init__
.
Python never checks for human misbehavior. The language philosophy is to assume that programmers are grown up adults and know what they are doing.
Since :
Returning None make more senss than raising an error.
E.G :
function_stack = [func1, func2, func3]
for f in function_stack :
a = f()
if a is not None :
# do something
No matter if f is f() is a function or a procedure. There is no such thing in Python. You can apply all the function, and process output if there is any.
Heh. Coming at it from a Java perspective, your question is obvious. It should throw an error.
But if you came at it from a Perl perspective, it's not obvious at all. You're setting a variable to no value, big deal.
It's all about the typing. Like Java, Python is strongly typed, but unlike Java, it is also dynamically typed. Most dynamically typed languages allow shenanigans like this.
It's beautiful ...
It returns None
in the case where val != 0
which to me make sense.
Python 2.6.1 (r261:67515, Jun 18 2009, 17:24:16)
[GCC 3.3.3 (SuSE Linux)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def test(val):
... if 0 == val:
... return 8
...
>>> a = test(8)
>>> print a
None
>>> print test(0)
8
>>>
Do you have any arguments why you think the behavior is wrong?
You can use c++ if you need strong compile time type checking but for python it seems extremely flexible and I assume that's what you want when you selected python for your task.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With