Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python functions call by reference

Tags:

python

In some languages you can pass a parameter by reference or value by using a special reserved word like ref or val. When you pass a parameter to a Python function it never alters the value of the parameter on leaving the function.The only way to do this is by using the global reserved word (or as i understand it currently).

Example 1:

k = 2  def foo (n):      n = n * n     #clarity regarding comment below      square = n      return square  j = foo(k) print j print k 

would show

>>4 >>2 

showing k to be unchanged.

In this example the variable n is never changed

Example 2:

n = 0 def foo():     global n     n = n * n     return n 

In this example the variable n is changed.

Is there any way in Python to call a function and tell Python that the parameter is either a value or reference parameter instead of using global?

Secondly, in the A level Cambridge exams they now say a function returns a single value whereas a procedure returns more than one value. I was taught a function has a return statement and procedure does not, during the 80s. Why is this now incorrect?

like image 359
Timothy Lawman Avatar asked Nov 08 '12 23:11

Timothy Lawman


2 Answers

There are essentially three kinds of 'function calls':

  • Pass by value
  • Pass by reference
  • Pass by object reference

Python is a PASS-BY-OBJECT-REFERENCE programming language.

Firstly, it is important to understand that a variable, and the value of the variable (the object) are two seperate things. The variable 'points to' the object. The variable is not the object. Again:

THE VARIABLE IS NOT THE OBJECT

Example: in the following line of code:

>>> x = [] 

[] is the empty list, x is a variable that points to the empty list, but x itself is not the empty list.

Consider the variable (x, in the above case) as a box, and 'the value' of the variable ([]) as the object inside the box.

PASS BY OBJECT REFERENCE (Case in python):

Here, "Object references are passed by value."

def append_one(li):     li.append(1) x = [0] append_one(x) print x 

Here, the statement x = [0] makes a variable x (box) that points towards the object [0].

On the function being called, a new box li is created. The contents of li are the SAME as the contents of the box x. Both the boxes contain the same object. That is, both the variables point to the same object in memory. Hence, any change to the object pointed at by li will also be reflected by the object pointed at by x.

In conclusion, the output of the above program will be:

[0, 1] 

Note:

If the variable li is reassigned in the function, then li will point to a separate object in memory. x however, will continue pointing to the same object in memory it was pointing to earlier.

Example:

def append_one(li):     li = [0, 1] x = [0] append_one(x) print x 

The output of the program will be:

[0] 

PASS BY REFERENCE:

The box from the calling function is passed on to the called function. Implicitly, the contents of the box (the value of the variable) is passed on to the called function. Hence, any change to the contents of the box in the called function will be reflected in the calling function.

PASS BY VALUE:

A new box is created in the called function, and copies of contents of the box from the calling function is stored into the new boxes.

Hope this helps.

like image 150
Shobhit Verma Avatar answered Sep 23 '22 21:09

Shobhit Verma


You can not change an immutable object, like str or tuple, inside a function in Python, but you can do things like:

def foo(y):   y[0] = y[0]**2  x = [5] foo(x) print x[0]  # prints 25 

That is a weird way to go about it, however, unless you need to always square certain elements in an array.

Note that in Python, you can also return more than one value, making some of the use cases for pass by reference less important:

def foo(x, y):    return x**2, y**2  a = 2 b = 3 a, b = foo(a, b)  # a == 4; b == 9 

When you return values like that, they are being returned as a Tuple which is in turn unpacked.

edit: Another way to think about this is that, while you can't explicitly pass variables by reference in Python, you can modify the properties of objects that were passed in. In my example (and others) you can modify members of the list that was passed in. You would not, however, be able to reassign the passed in variable entirely. For instance, see the following two pieces of code look like they might do something similar, but end up with different results:

def clear_a(x):   x = []  def clear_b(x):   while x: x.pop()  z = [1,2,3] clear_a(z) # z will not be changed clear_b(z) # z will be emptied 
like image 45
dave mankoff Avatar answered Sep 21 '22 21:09

dave mankoff