103 lines
3.6 KiB
Plaintext
103 lines
3.6 KiB
Plaintext
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
|
|
|
|
|
|
|
|
|