简体   繁体   中英

Different number of return values in Python function

Is it okay/good practice to return different number of return values from a function in Python? If yes, how should the caller handle the return values? eg

def func():
    if(condition_1):
        return 1,2
    if(condition_2):
        return 1
    if(condition_3):
        return 1,2,3,4

Note: condition_1,condition_2 and condition_3 are local to the function func so the caller has no idea how many values will be returned.

It's okay to return multiple values, but you must keep all your returns in same form/type for using:

def func():
    if(condition_1):
        return 1, 2
    if(condition_2):
        return 1,    # return a tuple same as the others
    if(condition_3):
        return 1, 2, 3, 4

Is it pythonic for a function to return multiple values? have a great explanation in this.

But in your case, it depends on your use-case. If you know how to handle returning data, then there is no problem in using this. Like:

def func():
    if(condition_1):
        return a,b
    if(condition_2):
        return (a, )
    if(condition_3):
        return c,d,e,f
    if(condition_4):
        return a,b

vals = func()
if len(vals) == 2:
    # We are sure that we will get `a,b` in return
    do something ...
elif len(vals) == 3:
    ...

In example above, function that will process vals tuple knows how to handle returning data according to some criteria. It have 2 return possibilities that returns the same data!

If you know exactly how to handle data, then it is ok to go with different number of returns. The key point in here is functions do a single job . If your have problems in recognizing the return values, then your function is doing more than one job or you must avoid using different number of arguments.

While this is subjective, I like to return dictionaries - it helps to avoid caring for the order of what is returned, I can have a partial return (3 elements out of 5 for instance) and it makes the code more readable.

def func():
    if(condition_1):
        return {'name': 'Joe', 'age': 32}
    if(condition_2):
        return {'name': 'Mary'}

res = func()
name = res.get('name', 'unknown')
age = res.get('age', 0)

I would avoid this. In general (although there are occasionally exceptions), as other people have mentioned, it is a good idea to return the same type of object from each branch of a function. However, this goes deeper than just wrapping singular return values in one-element tuples - consider a pattern whereby you return the same number of things (in the same order), and using None or some type-specific 'null' value (the Null Object Pattern ) for any that don't apply to that branch.

This means client code can always do this:

a, b, c, d, e = func()

and ignore any values it doesn't care about. With the null object pattern also in the mix, then even code that cares about the potentially non-existent values might not have to special case them. If you vary the length of the tuple, every call has to be prepared for the results of any branch, which means it nearly has to match your branches.

A really nice way, for you and for calling code, to enforce this kind of pattern is to use collections.namedtuple . This also has the nice benefit of making your code immediately more self-documenting.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM