109 lines
3.4 KiB
Plaintext
109 lines
3.4 KiB
Plaintext
|
From: faassen at pop.vet.uu.nl (Martijn Faassen)
|
||
|
Date: Thu, 22 Apr 1999 19:49:24 +0200
|
||
|
Subject: Pointers to variables
|
||
|
References: <19990422121403.A279051@vislab.epa.gov>
|
||
|
Message-ID: <371F6124.48EA9794@pop.vet.uu.nl>
|
||
|
Content-Length: 3214
|
||
|
X-UID: 11
|
||
|
|
||
|
Randall Hopper wrote:
|
||
|
>
|
||
|
> This doesn't work:
|
||
|
>
|
||
|
> for ( var, str ) in [( self.min, 'min_units' ),
|
||
|
> ( self.max, 'max_units' )]:
|
||
|
> if cnf.has_key( str ):
|
||
|
> var = cnf[ str ]
|
||
|
> del cnf[ str ]
|
||
|
>
|
||
|
> It doesn't assign values to self.min, self.max (both integers). The values
|
||
|
> of these variables are inserted into the tuples and not references to the
|
||
|
> variables themselves, which is the problem.
|
||
|
>
|
||
|
> How can I cause a reference to the variables to be stored in the tuples
|
||
|
> instead of their values?
|
||
|
|
||
|
Hi there,
|
||
|
|
||
|
I've been trying to understand the purpose of the code in your fragment
|
||
|
and your question for a minute or so, but I'm not entirely sure I get it
|
||
|
yet.
|
||
|
|
||
|
I'm assuming what you want is to get 'cnf[str]' assigned to self.min or
|
||
|
self.max.
|
||
|
|
||
|
What you could do is something like this:
|
||
|
|
||
|
for str in ('min_units', 'max_units'):
|
||
|
if cnf.has_key(str):
|
||
|
setattr(self, str, cnf[str])
|
||
|
del cnf[str]
|
||
|
|
||
|
Tuples, by the way are immutable, so you can't change what values their
|
||
|
elements point to after they've been created (though if these values
|
||
|
point to other things themselves you can change that). That is, you
|
||
|
can't do this:
|
||
|
|
||
|
foo = (value1, value2)
|
||
|
foo[0] = "hey"
|
||
|
|
||
|
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:
|
||
|
|
||
|
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!
|
||
|
# mylist[0] = "Bar" -- doesn't work, makes mylist[0] point elsewhere
|
||
|
|
||
|
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 */
|
||
|
|
||
|
/* has the data *variable_i_want_to_change changed? no. I hope! :)*/
|
||
|
|
||
|
I don't expect this explained a lot. I feel like Tim Peters somehow...
|
||
|
:)
|
||
|
|
||
|
Regards,
|
||
|
|
||
|
Martijn
|
||
|
|
||
|
|
||
|
|
||
|
|