From: mlv at pobox.com (Michael Vezie)
Date: 26 Apr 1999 15:35:18 -0400
Subject: Pointers to variables
References: <19990422121403.A279051@vislab.epa.gov> <371F6124.48EA9794@pop.vet.uu.nl>
Message-ID: <7g2f5m$kl6$1@mlv.mit.edu>
Content-Length: 3364
X-UID: 1480                                                  

In article <371F6124.48EA9794 at pop.vet.uu.nl>,
Martijn Faassen  <M.Faassen at vet.uu.nl> wrote:
>But, if you'd use a mutable list, you still run into trouble. If you say
>this:
>
>    mylist = [None]                         # list with a single element
>None
>    variable_i_want_to_change = "Foo"       # a variable I want to
>change
>    mylist[0] = variable_i_want_to_change   # okay, mylist[0] points to
>same data
>    mylist[0] = "Bar"                       # now mylist[0] points to
>different data
>
>then 'variable_i_want_to_change' won't change. You've simply changed
>what value mylist[0] points at. This is because a string (and integers
>etc) are immutable values in Python. If you use a mutable value such as
>a dictionary, you get this:

I don't think it has anything to do with mutable or not.  mylist[0] 
simply points (at first) to the same object (string) that 
variable_i_want_to_change (hereafter called 'var2chg').  Then, 
at the second assignment, mylist[0] points to something different.
If var2chg were an array or dictionary, it would make no difference; 
mylist[0] would still, after the second assignment, be "Bar".


>    mylist = [None]
>    variable_i_want_to_change = {}
>    mylist[0] = variable_i_want_to_change
>    mylist[0]["some key"] = "bar" # indeed changes
>variable_i_want_to_change!

This is different from the other examples.  Here, you dereference 
mylist[0] (which is still pointing to the same object that var2chg
points to).  So the common object that they both point to changes.
Strictly speaking, you aren't changing var2chg, just that which it 
(and mylist[0]) points to.


>    # mylist[0] = "Bar" -- doesn't work, makes mylist[0] point elsewhere

Well, it works as expected.  It changes mylist[0], not what mylist[0] 
references.


>I suspect I'm making things sound horribly complicated when they aren't
>really. I can keep all this in my head easily, it's just hard
>communicating it. I can understand the confusion with pointers from C,
>but note that this is the actual semi-equivalent C code (of the first
>fragment, not the dict one, and using ints instead of strings):
>
>/* Initialize the variables, assume easy allocate functions which do all
>the 
>   malloc() calls I don't want to figure out right now */
>int** mylist = allocate_list();
>*mylist[0] = 0;  
>/* now we have a list with a pointer to an int value, which is 0 */
>
>int* variable_i_want_to_change = allocate_int();
>*variable_i_want_to_change = 1;
>/* now we have a variable which points to an int value, which is 1 */
>
>*mylist[0] = *variable_i_want_to_change;
>/* now the data mylist[0] points at becomes 1 too */
>
>*mylist[0] = 2;
>/* now the data mylist[0] points at becomes 2 */

I wonder if this is how it goes.  I've not dived into the python 
engine code, so I don't know.  Are immutable objects stored as 
objects or just as the data?  In the grand scheme of things, it 
really makes no difference.  If there were an "add" method for 
ints (so you could say:

	var2chg = 5
	var2chg.add(3)

and have var2chg have a value of 8), then it would obviously be 
a concern.  But you can't, so it really doesn't matter at the 
python level whether:

	a = 5
	b = a

means that b and a point to the same object, or to separate 
values of 5.  If you could do b.add(3) and suddenly have a 
with a value of 8, then it would.

Michael




