[Tutor] pointers for python?

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Tue Oct 7 11:47:29 EDT 2003


> void test(int a)
> {
> 	a++;
> 	printf("Integer value + 1 is: %d\n",a);
> }
>
> if you were to call this like so:
>
> int t = 42;
> test(t);



Hi Thomi,


Ok, looks like we can talk C code then.  *grin*


When we say something like this in Python:

###
def test(a):
    a = a + 1
    print a

if __name__ == '__main__':
    a = 42
    test(a)
    print a
###



A really rough translation to C code might be something like this:

###
int* makeIntObject(int number) {
    int* result = (int*)(malloc(sizeof(int)));
    *result = number;
    return result;
}


void test(int *a) {
    a = makeIntObject(*a + 1);
    printf("%d\n", *a);
}


void main() {
    int* a = makeIntObject(42);
    test(a);
    printf("%d\n", *a);
}
###


In Python, all names are actually represented as pointers to objects on
the heap --- none of the Python objects are actually on the stack!



What's important to see is that Python treats certain types as
"immutable": the language provides no way of mutating an immutable object.
For example, when we say:

###
a = a + 1
###

what is actually happening is the construction of a new integer, not the
overwriting of an old one.  '+' is defined as an operation that constructs
a new integer object, given two integer operands.



To see this more clearly, we can use a builtin() function called id()
that's equivalent to the 'address-of' (&) operator in C:

###
>>> a = 42
>>> b = a
>>> id(a)
135364256
>>> id(b)
135364256
###

The object pointed to by both 'a' and 'b' are identical: the integer "box"
lives at location 135364256.  But when we start doing arithmetic:

###
>>> a = a + 1
>>> id(a)
135364184
>>> id(b)
135364256
###

the object that 'a' points to now is distinct from what it originally
pointed to.




> this would print 43, but the variable "t" (in the main scope of the
> program)  would remain 42, because the function test() was operating on
> a copy of the variable, not the variable itself. is this basically
> correct?

Not exactly: what's happening is that arithmetic in Python constructs a
whole new integer.  You're probably thinking:


    a
  ------
  | 42 |
  ------


But what Python is actually doing is more like:

                     ------
    a -------------->| 42 |
                     ------


It's all uniform, which is what allows Python lists to contain all kinds
of things without wackiness.  When we say:

###
l = [1, 'two']
###


we can model this as:


    l --------------->  ---------
                        | . | . |
                        --+---+--
                          |   \
                          |    \
                          |     \
                          V      V
                       -----    ---------
                       | 1 |    | "two" |
                       -----    ---------

It has to be pointers, or else Python lists wouldn't be able to hold
different types of objects.



Integers manipulation is all "immutable" because the language provides no
way of mutating a number.  This idea might be clearer with tuples, which
are also immutable:

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


Same idea --- the type doesn't allow internal mutation, although it's
perfectly ok to redirect 't' by constructing another tuple out of the
pieces of the old one:

###
>>> t = (42,) + t[1:]
>>> t
(42, 2, 3)
###



Anyway, hope this clears some of the confusion!  (Or at least, doesn't
contribute to the confusion... *grin*)  Please feel free to ask more
questions about this; it is a slightly confusing topic if you're coming
from a C background, but it should make sense very soon.


Good luck!




More information about the Tutor mailing list