[Tutor] How to do call by reference (or equiv.) in Py?

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Fri Nov 22 16:53:01 2002


On Fri, 22 Nov 2002, Aztech Guy wrote:

> Hi fellow Pythonistas,
>
> I have a C background - but am a Py newbie ...

Hi Aztech,


We can think of all "variable names" in Python as pointers to objects.
In fact, that's pretty much what's going on.

###
>>> x = 42
>>> y = x
>>> x
42
>>> y
42
>>> id(x)
135364384
>>> id(y)
135364384
###

The 'id()' function, as currently implemented in CPython, is a way of
seeing if two names are pointing to the "same" object.  Think of it as C's
'&' operator.  In Python, since we don't have pointer arithmetic, the id()
function is fairly useless in regular Python programming.



The key here is that arithmetic in Python (or any manipulation on an
"immutable" data type), does not modify the object, though: it dynamically
constructs new objects:

###
>>> x = x + 1
>>> x
43
>>> y
42
>>> id(x)
135364312
>>> id(y)
135364384
###

Note that, by this point, 'x' no longer points to the object located at
135364384: it's now pointed to a newly allocated object at location
135364312.  From 'y''s perspective, nothing changes.



Here's an analogous situation in C:

/***/
#include <stdio.h>
int* sum(int *x, int *y) {
    int *z = malloc(sizeof(int));
    *z = *x + *y;
    return z;
}


int main() {
    int *x, *y, *sum;
    x = malloc(sizeof(int));
    *x = 42;
    y = x;
    sum = add(x, y);
    printf("%d + %d = %d", *x, *y, *sum);
    return 0;
}
/***/


Here, we're passing pointers around, but since arithmetic manipulations
don't actually mungle up the objects, none of the objects get touched.
Python's numeric types all behave immutably.


The only reason you're not seeing modifications in your values is because
you're working on immutable types that don't do in-place modification.
Strings, too, are considered "immutable" because all string manipulation
generates newly constructed strings: Python does not do modifications
in-place, which is why something like:

###
>>> greeting = 'hallo'
>>> greeting[1] = 'e'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment
###

is not allowed.



Lists, on the other hand, are mutable, and index assignment does behave
just like the arrays that you're used to in C:

###
>>> mylist = list('hallo')
>>> mylist
['h', 'a', 'l', 'l', 'o']
>>> mylist[1] = 'e'
>>> mylist
['h', 'e', 'l', 'l', 'o']
>>> def rotate(some_list):
...     first = some_list.pop(0)
...     some_list.append(first)
...
>>> mylist
['h', 'e', 'l', 'l', 'o']
>>> rotate(mylist)
>>> mylist
['e', 'l', 'l', 'o', 'h']
>>> rotate(mylist)
>>> mylist
['l', 'l', 'o', 'h', 'e']
###


I was in a hurry while writing this, so please feel free to ask more
questions on the fuzzy points.  Good luck!