Is there a way in Python to return a value via an output parameter?
Question:
Some languages have the feature to return values using parameters also like C#.
Let’s take a look at an example:
class OutClass
{
static void OutMethod(out int age)
{
age = 26;
}
static void Main()
{
int value;
OutMethod(out value);
// value is now 26
}
}
So is there anything similar in Python to get a value using parameter, too?
Answers:
Pass a list or something like that and put the return value in there.
You mean like passing by reference?
For Python object the default is to pass by reference. However, I don’t think you can change the reference in Python (otherwise it won’t affect the original object).
For example:
def addToList(theList): # yes, the caller's list can be appended
theList.append(3)
theList.append(4)
def addToNewList(theList): # no, the caller's list cannot be reassigned
theList = list()
theList.append(5)
theList.append(6)
myList = list()
myList.append(1)
myList.append(2)
addToList(myList)
print(myList) # [1, 2, 3, 4]
addToNewList(myList)
print(myList) # [1, 2, 3, 4]
Python can return a tuple of multiple items:
def func():
return 1,2,3
a,b,c = func()
But you can also pass a mutable parameter, and return values via mutation of the object as well:
def func(a):
a.append(1)
a.append(2)
a.append(3)
L=[]
func(L)
print(L) # [1,2,3]
In addition, if you feel like reading some code, I think that pywin32
has a way to handle output parameters.
In the Windows API it’s common practice to rely heavily on output parameters, so I figure they must have dealt with it in some way.
You can do that with mutable objects, but in most cases it does not make sense because you can return multiple values (or a dictionary if you want to change a function’s return value without breaking existing calls to it).
I can only think of one case where you might need it – that is threading, or more exactly, passing a value between threads.
def outer():
class ReturnValue:
val = None
ret = ReturnValue()
def t():
# ret = 5 won't work obviously because that will set
# the local name "ret" in the "t" function. But you
# can change the attributes of "ret":
ret.val = 5
threading.Thread(target = t).start()
# Later, you can get the return value out of "ret.val" in the outer function
Adding to Tark-Tolonen‘s answer:
Please absolutely avoid altering the object reference of the output argument in your function, otherwise the output argument won’t work. For instance, I wish to pass an ndarray into a function my_fun
and modify it
def my_fun(out_arr)
out_arr = np.ones_like(out_arr)
print(out_arr) # prints 1, 1, 1, ......
print(id(out_arr))
a = np.zeros(100)
my_fun(a)
print(a) # prints 0, 0, 0, ....
print(id(a))
After calling my_fun
, array a
stills remains all zeros since the function np.ones_like
returns a reference to another array full of ones and assigns it to out_arr
instead of modifying the object reference passed by out_arr
directly. Running this code you will find that two print(id())
gives different memory locations.
Also, beware of the array operators from numpy, they usually returns a reference to another array if you write something like this
def my_fun(arr_a, arr_b, out_arr)
out_arr = arr_a - arr_b
Using the -
and =
operator might cause similar problems. To prevent having out_arr
‘s memory location altered, you can use the numpy functions that does the exactly same operations but has a out
parameter built in. The proceeding code should be rewritten as
def my_fun(arr_a, arr_b, out_arr):
np.subtract(arr_a, arr_b, out = out_arr)
And the memory location of out_arr
remains the same before and after calling my_fun
while its values gets modified successfully.
Some languages have the feature to return values using parameters also like C#.
Let’s take a look at an example:
class OutClass
{
static void OutMethod(out int age)
{
age = 26;
}
static void Main()
{
int value;
OutMethod(out value);
// value is now 26
}
}
So is there anything similar in Python to get a value using parameter, too?
Pass a list or something like that and put the return value in there.
You mean like passing by reference?
For Python object the default is to pass by reference. However, I don’t think you can change the reference in Python (otherwise it won’t affect the original object).
For example:
def addToList(theList): # yes, the caller's list can be appended
theList.append(3)
theList.append(4)
def addToNewList(theList): # no, the caller's list cannot be reassigned
theList = list()
theList.append(5)
theList.append(6)
myList = list()
myList.append(1)
myList.append(2)
addToList(myList)
print(myList) # [1, 2, 3, 4]
addToNewList(myList)
print(myList) # [1, 2, 3, 4]
Python can return a tuple of multiple items:
def func():
return 1,2,3
a,b,c = func()
But you can also pass a mutable parameter, and return values via mutation of the object as well:
def func(a):
a.append(1)
a.append(2)
a.append(3)
L=[]
func(L)
print(L) # [1,2,3]
In addition, if you feel like reading some code, I think that pywin32
has a way to handle output parameters.
In the Windows API it’s common practice to rely heavily on output parameters, so I figure they must have dealt with it in some way.
You can do that with mutable objects, but in most cases it does not make sense because you can return multiple values (or a dictionary if you want to change a function’s return value without breaking existing calls to it).
I can only think of one case where you might need it – that is threading, or more exactly, passing a value between threads.
def outer():
class ReturnValue:
val = None
ret = ReturnValue()
def t():
# ret = 5 won't work obviously because that will set
# the local name "ret" in the "t" function. But you
# can change the attributes of "ret":
ret.val = 5
threading.Thread(target = t).start()
# Later, you can get the return value out of "ret.val" in the outer function
Adding to Tark-Tolonen‘s answer:
Please absolutely avoid altering the object reference of the output argument in your function, otherwise the output argument won’t work. For instance, I wish to pass an ndarray into a function my_fun
and modify it
def my_fun(out_arr)
out_arr = np.ones_like(out_arr)
print(out_arr) # prints 1, 1, 1, ......
print(id(out_arr))
a = np.zeros(100)
my_fun(a)
print(a) # prints 0, 0, 0, ....
print(id(a))
After calling my_fun
, array a
stills remains all zeros since the function np.ones_like
returns a reference to another array full of ones and assigns it to out_arr
instead of modifying the object reference passed by out_arr
directly. Running this code you will find that two print(id())
gives different memory locations.
Also, beware of the array operators from numpy, they usually returns a reference to another array if you write something like this
def my_fun(arr_a, arr_b, out_arr)
out_arr = arr_a - arr_b
Using the -
and =
operator might cause similar problems. To prevent having out_arr
‘s memory location altered, you can use the numpy functions that does the exactly same operations but has a out
parameter built in. The proceeding code should be rewritten as
def my_fun(arr_a, arr_b, out_arr):
np.subtract(arr_a, arr_b, out = out_arr)
And the memory location of out_arr
remains the same before and after calling my_fun
while its values gets modified successfully.