1

In Python, I would like to write a function that has a variable number of return values and that is easily dealt with. Something like

def test(a):
    if a > 0:
        return True
    else:
        return False, 123, 'foo'

can be used like

out = test(-5)

but a disadvantage I see here is that the user would have to check if the return argument is a tuple, and act accordingly. The meaning of the return values is not very explicit.

A variant would be to use dictionaries as return values but since I haven't ever seen this in any code, it feels a little hackish.

Are there better ways to organize the code?

4
  • How do you intend for the caller to use the return value? Commented Sep 10, 2013 at 16:39
  • 1
    The example is a little contrived, so it's unclear how you want to use the tuple return, and it can get confusing and overly complex in the code if you have variants depending upon the condition. If you really do need to return a tuple of information, you could make all the returns the same kind of tuple and avoid the check, so return True, None, None in the True case, for example. Commented Sep 10, 2013 at 16:44
  • 2
    ...has a variable number of return values and that is easily dealt with... I believe these requirements work against each other. Commented Sep 10, 2013 at 16:46
  • 2
    A lot of libraries(e.g. numpy and matplotlib just to cite two of them) in these circumstances always return a tuple/list, even with a single return value. This makes code using the return value simpler. Also, if the user knows that the function will return a 1-element tuple/list he can simply do out, = test(...) (note the comma) to automatically unpack the single value. Commented Sep 10, 2013 at 16:51

2 Answers 2

3

Always ensure that your return values are of a type which can be used consistently with each other.

In python, the type of a function is implicit. This means that the programmer can create a function of any type whatsoever (which is great), but it means that you, as a programmer have to take care to choose the type. In short: you should describe the return type in the docstring, and if it sounds like a bad idea, or a difficult function to use, it is.

The right thing here is either:

def test(a):
    ''' Always returns a 3-tuple, composed of Flag,data,data. Data may be None '''
    if a > 0:
        return True, None, None
    else:
        return False, 123, 'foo'

flag,data1,data2 = test(a)

or

def test(a):
    ''' Always returns a tuple, composed of a Flag, followed by 0 or more data items '''
    if a > 0:
        return True,
    else:
        return False, 123, 'foo'

return = test(a)
flag,rest = return[0],return[1:]
for x in rest: print x
Sign up to request clarification or add additional context in comments.

Comments

3

but a disadvantage I see here is that the user would have to check if the return argument is a tuple, and act accordingly. The meaning of the return values is not very explicit.

In such scenario, always return a tuple, that would keep a consistency with handling the return type

>>> def test(a):
    if a > 0:
        return True,
    else:
        return False, 123, 'foo'

>>> out = test(-5)
>>> out
(False, 123, 'foo')
>>> out = test(1)
>>> out
(True,)

2 Comments

+1 I was about to post this too. Heterogeneous return types, OK. Variable length return, OK. Both at the same time? Not such a big fan.
With extended tuple unpacking you could do flag, *rest = test(-5) (or explicitly specify the values that are guaranteed to be returned). This might allow to avoid a bit of code to deal with all the cases.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.