[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