[Tutor] pointers for python?

Gonçalo Rodrigues op73418 at mail.telepac.pt
Tue Oct 7 08:51:17 EDT 2003


On Tue, 7 Oct 2003 21:24:54 +1300, you wrote:

>-----BEGIN PGP SIGNED MESSAGE-----
>Hash: SHA1

[text snnipped]

>> What we're talking about, then, is just a matter of "mutability" and
>> "immutability".  Maybe we should refocus the subject away from pointers
>> and to immutability concepts.
>>
>
>AFAIK (And I'm no expert), in C, whenever a function is called, a *copy* of 
>the variables passed to it are made, and the function uses that copy, like 
>this:
>
>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);
>
>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?
>
>However, when you use pointers in C, you are passing an address in memory, 
>which can be used like a variable. However, because you are passing the 
>original address, the function operates on the original varibale, not a copy 
>(this can of course be useful when you're dealing with larger structures, as 
>it saves the program chewing memory and CPU cycles to copy something which 
>you were effectively going to change anyway).
>
>...which brings us back to python. Evidently, python doesn't do this, with 
>*some* types...which is supreemly wierd.. IMO anyway...
>

Python treats *every* object in the same way. Repeat after me: Python
treats every object in the same way. 

 Whenever you do an assignment as in

my_var = <some Python object>

Python just adds an entry to the current namespace. Namespaces are
essentially dictionaries, so you can view the above as, in Python
syntax,

current_namespace["my_var"] = reference_to_<some Python object>

You can think of reference_to_<some Python object> as a pointer (and
under the hoods it is). Take notice though, that you can never get a
hold of the pointer itself, because Python automatically dereferences,
so that whenever you have

my_var

Python substitutes my_var by (mixing Python and C syntax freely) 

*current_namespace["my_var"]

Now, when you call a function

some_function(my_var)

Part of the function call is just adding entrance my_var in the
*local* namespace of the function, that is

some_function_namespace["my_var"] = my_var

The rhs my_var evaluated according to the rule above. So in your
example

>t = 42;
>test(t);

Python does the following (once again mixing Python and C syntax):

. Create the object 42 (in the heap)

. Stick a reference to it in the current namespace:

current_namespace["t"] = &<42>

. In calling the function test add an entry to test's namespace as in

test_namespace["t"] = &<t>

But this is, since Python automatically dereferences, 

test_namespace["t"] = &<42>

So what you have in your local namespace is just another reference to
42. No copies of objects are involved - only copies of pointers if you
want to think in terms of the above model.

Now this mental model works for *any* Python object. So suppose we
have 

>t = [];
>test(t);

So you end up, in the local namespace of test, with reference to the
*same list* referenced by t in the outer namespace. But a list is a
mutable object. This means that there are methods that change the
object inplace in contrast to immutable objects (such as numbers and
strings) where *every* method returns a *new* object -- and therefore
you can't change the original object, thus the immutability. Since a
list is mutable you can, within the body of test, do

t.append(<whatever>)

and since the outer t references the *same* list, the changes will be
visible. That is, in the outer namespace t is [<whatever>].

I hope I have made myself understood. Any other question, just holler.

With my best regards,
G. Rodrigues



More information about the Tutor mailing list