Does Python have any equivalent of nargout in MATLAB? I find nargout a very neat approach if we want to keep the number of return parameters flexible. Is there a way I can find out how many output parameters have been requested? Something like the following pseudo-python-code:
def var_returns_func(a):
"""
a is a 1D numpy array
"""
if nargout==1: return a.sum()
elif nargout==2: return a.sum(),a.std()
So if I call this function as mean = var_returns_func(someNumPyarray)
, it should return a single value. But if I call it as mean,std = var_returns_func(someNumPyarray)
, it should return 2 values.
Is there a Pythonic way of doing this? Or a hacky way?
In Matlab, the number of output arguments is actually one of the inputs to a function. This is not the case in Python and so you have set up the function's interface to reflect this differently.
For example, here's a function that applies upper() to a group of strings, and the user can expect the the number of inputs equals the number of outputs. The syntax is also very similar to Matlab's.
What I tend to do is make my function return everything (as elements of a tuple), then only unpack the ones I need:
Here Im returning everything, but only assigning the 1st 2nd and 4th variables to variables I will use in the calling scope. The
_
variable is a throwaway to act as a placeholder for the variables I dont want/need.I cannot speak for
nargout
in MATLAB as I do not know it and I cannot imagine how it should be used correctly. However, you may want to change you view to what a Python function (or method) really does).Actually, Python always returns exactly one value. Or it is None, or it is a single value of some specific type, or it is a single object of the
tuple
type.If there is no
return
command, the function returnsNone
if the function body ends. It is the same as if you explicitly wrotereturn
without arguments at the end of body, orreturn None
at the end of body.If you use
return None
(theNone
can be stored in a variable) orreturn
without arguments, theNone
is returne to the caller.If you
return single
, thesingle
object is return to the caller.If you
return v1, v2, v3
, you actually return a tuple(v1, v2, v3)
. It is just a syntactic sugar that you need not to write the parentheses.The
result1, result2, result3 = f()
in the case is just another syntactic sugar. Thef()
returns the tuple and its elements are automatically extracted to the given variables. You actually do:or
Actually, Python does not allow to define output arguments as it is usual in other languages. You can think in terms you are passing addresses of the argument objects and if the passed object allows to be modified, you can modify it. But you can never get a new result to a passed argument that had initially
None
value, for example. You cannot assign a Python variable via output argument of the function -- no mechanism like that in Python.The only natural and direct way to return newly created values (objects) from inside the function is to use the
return
command. However, a Python function does not limits you how many arguments can be returned. (Well, always a single one that can be later broken to elements if it was a tuple.)If you want to test in the caller code what was actually returned, you can write your own function that does something special in cases where the following values were returned:
None
,single
, a tuple of some length (len(t)
can be used to get the number of elements in the returned tuplet
). Your function can also test the type ofsingle
or of the each of the tuple elements and work accordingly.The function can't know what is going to be done with the return value, so it can't know how many are needed. What you could do is pass
nargout
as an argument to your function and use that to decide what to return:This is an example of "explicit is better than implicit" as a Python philosophy. If you want two arguments out, you have to say explicitly that you want two arguments out. Implicitly deciding based on looking into the future to see what is going to be done with the result is discouraged in Python. It's perfectly possible to do
a = f(x)
and want to get a two-element tuple in a.For examples like yours, there are lots of better ways. One is to just do
mean, std = a.mean(), a.std()
, or more generallyx, y = someFunc(a), otherFunc(a)
. If this particular combination of values is commonly needed, and there is some expensive computation shared by both operations that you don't want to duplicate, make a third function that clearly returns both and dox, y = funcThatReturnsTwoThings(a)
. All of these are explicit ways of keeping functions separate if they do different things.I have a strange idea ...
I really miss Matlab now :D
Improved by: