Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python procedure return values [closed]

Tags:

python

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.

like image 370
James Avatar asked Oct 13 '09 21:10

James


People also ask

Does a procedure return a value in Python?

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.

How do you ignore a return value in Python?

1 Answer. To Ignore python multiple return value you can use the "_" as a variable name for the elements of the tuple.

Does a Python function stop at return?

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.


4 Answers

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__.

like image 150
SilentGhost Avatar answered Nov 09 '22 20:11

SilentGhost


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 :

  • Python is an autodocumented language, so you'll know in a blink what returns a function;
  • Python uses duck typing, so getting None by default can ease dynamic function call a lot.

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.

like image 27
e-satis Avatar answered Nov 09 '22 18:11

e-satis


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.

like image 41
Satanicpuppy Avatar answered Nov 09 '22 20:11

Satanicpuppy


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.

like image 30
stefanB Avatar answered Nov 09 '22 18:11

stefanB