Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #16875 > unrolled thread
| Started by | Catherine Moroney <Catherine.M.Moroney@jpl.nasa.gov> |
|---|---|
| First post | 2011-12-08 12:17 -0800 |
| Last post | 2011-12-10 00:41 +0000 |
| Articles | 7 — 7 participants |
Back to article view | Back to comp.lang.python
tracking variable value changes Catherine Moroney <Catherine.M.Moroney@jpl.nasa.gov> - 2011-12-08 12:17 -0800
Re: tracking variable value changes Ian Kelly <ian.g.kelly@gmail.com> - 2011-12-08 14:50 -0700
Re: tracking variable value changes Ben Finney <ben+python@benfinney.id.au> - 2011-12-09 09:06 +1100
Re: tracking variable value changes Arnaud Delobelle <arnodel@gmail.com> - 2011-12-08 22:10 +0000
Re: tracking variable value changes Andrea Crotti <andrea.crotti.0@gmail.com> - 2011-12-09 12:43 +0000
Re: tracking variable value changes alex23 <wuwei23@gmail.com> - 2011-12-11 21:45 -0800
Re: tracking variable value changes Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-10 00:41 +0000
| From | Catherine Moroney <Catherine.M.Moroney@jpl.nasa.gov> |
|---|---|
| Date | 2011-12-08 12:17 -0800 |
| Subject | tracking variable value changes |
| Message-ID | <jbr607$eer$1@news.jpl.nasa.gov> |
Hello,
Is there a way to create a C-style pointer in (pure) Python so the
following code will reflect the changes to the variable "a" in the
dictionary "x"?
For example:
>>> a = 1.0
>>> b = 2.0
>>> x = {"a":a, "b":b}
>>> x
{'a': 1.0, 'b': 2.0}
>>> a = 100.0
>>> x
{'a': 1.0, 'b': 2.0} ## at this point, I would like the value
## associated with the "a" key to be 100.0
## rather than 1.0
If I make "a" and "b" numpy arrays, then changes that I make to the
values of a and b show up in the dictionary x.
My understanding is that when I redefine the value of "a", that Python
is creating a brand-new float with the value of 100.0, whereas when I
use numpy arrays I am merely assigning a new value to the same object.
Is there some way to rewrite the code above so the change of "a" from
1.0 to 100.0 is reflected in the dictionary. I would like to use
simple datatypes such as floats, rather than numpy arrays or classes.
I tried using weakref's, but got the error that a weak reference cannot
be created to a float.
Catherine
[toc] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2011-12-08 14:50 -0700 |
| Message-ID | <mailman.3456.1323381077.27778.python-list@python.org> |
| In reply to | #16875 |
On Thu, Dec 8, 2011 at 1:17 PM, Catherine Moroney
<Catherine.M.Moroney@jpl.nasa.gov> wrote:
> Hello,
>
> Is there a way to create a C-style pointer in (pure) Python so the following
> code will reflect the changes to the variable "a" in the
> dictionary "x"?
>
> For example:
>
>>>> a = 1.0
>>>> b = 2.0
>>>> x = {"a":a, "b":b}
>>>> x
> {'a': 1.0, 'b': 2.0}
>>>> a = 100.0
>>>> x
> {'a': 1.0, 'b': 2.0} ## at this point, I would like the value
> ## associated with the "a" key to be 100.0
> ## rather than 1.0
>
> If I make "a" and "b" numpy arrays, then changes that I make to the values
> of a and b show up in the dictionary x.
>
> My understanding is that when I redefine the value of "a", that Python
> is creating a brand-new float with the value of 100.0, whereas when I use
> numpy arrays I am merely assigning a new value to the same object.
Sort of. In the code above, you are binding a and x["a"] to the same
float object. Then when you do "a = 100.0", you are rebinding a but
not x["a"]. In the case of arrays it's the same story, except that
you can also *modify* the contents of the array instead of rebinding
to a new array. In that case both a and x["a"] are still bound to the
original array, the contents of which have changed.
You can get the same effect with a float by putting it in a container
object and binding both variables to the same container objects rather
than to the float directly. Then, to change the value, change the
contents of the container object. What you use as a container object
is up to you. Some use a 1-element list, although I find that ugly.
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2011-12-09 09:06 +1100 |
| Message-ID | <87aa723eif.fsf@benfinney.id.au> |
| In reply to | #16875 |
Catherine Moroney <Catherine.M.Moroney@jpl.nasa.gov> writes:
> Is there a way to create a C-style pointer in (pure) Python so the
> following code will reflect the changes to the variable "a" in the
> dictionary "x"?
No, Python doesn't do pointers. Rather, objects have references and
that's how the program accesses the objects.
> For example:
>
> >>> a = 1.0
> >>> b = 2.0
> >>> x = {"a":a, "b":b}
> >>> x
> {'a': 1.0, 'b': 2.0}
> >>> a = 100.0
> >>> x
> {'a': 1.0, 'b': 2.0} ## at this point, I would like the value
> ## associated with the "a" key to be 100.0
> ## rather than 1.0
You might like that, but it's just not how Python works.
Python doesn't have C-style pointers.
Python also doesn't have variables (even though the documentation uses
that term; IMO it's a mistake, and leads to confusion similar to this).
What Python has are references to objects. One kind of reference is a
name; another kind of reference is a value in a dictionary.
The assignment operator ‘=’ is the binding operator. It binds the
reference on the left side to the object on the right side.
> If I make "a" and "b" numpy arrays, then changes that I make to the
> values of a and b show up in the dictionary x.
Yes, because the objects are mutable; you can change them and existing
references are still referring to the same object. They don't “show up
in the dictionary”; the dictionary item is just referring to the same
object it did before you made the change.
> My understanding is that when I redefine the value of "a"
Please think of it, instead, as re-binding the name ‘a’ to a new value.
> that Python is creating a brand-new float with the value of 100.0,
Yes (or at least that's the abstraction being presented to you; it may
not be implemented exactly that way, but it's sufficient that we Python
programmers treat it that way).
> whereas when I use numpy arrays I am merely assigning a new value to
> the same object.
No, you're modifying the object.
A numpy array itself contains references. By altering one of the
elements in an array, you are re-binding one of its references to a
different number.
> Is there some way to rewrite the code above so the change of "a" from
> 1.0 to 100.0 is reflected in the dictionary. I would like to use
> simple datatypes such as floats, rather than numpy arrays or classes.
Please follow the Python tutorial <URL:http://docs.python.org/tutorial/>
from beginning to end. Not just read, but do it: work through the
exercises to understand what each one is teaching you.
That will give you a firm grounding in Python's data model, including
mutable and immutable types, references and binding.
Do bear in mind what I said above, though, about “variable” being a
misleading term, and ignore its implications from the C language.
--
\ “Good judgement comes from experience. Experience comes from |
`\ bad judgement.” —Frederick P. Brooks |
_o__) |
Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Arnaud Delobelle <arnodel@gmail.com> |
|---|---|
| Date | 2011-12-08 22:10 +0000 |
| Message-ID | <mailman.3457.1323382205.27778.python-list@python.org> |
| In reply to | #16875 |
On 8 December 2011 21:50, Ian Kelly <ian.g.kelly@gmail.com> wrote: > You can get the same effect with a float by putting it in a container > object and binding both variables to the same container objects rather > than to the float directly. Then, to change the value, change the > contents of the container object. What you use as a container object > is up to you. Some use a 1-element list, although I find that ugly. This kind of trick is not often necessary anyway. It may be a sign that there is a better approach to the problem that the OP is trying to solve. -- Arnaud
[toc] | [prev] | [next] | [standalone]
| From | Andrea Crotti <andrea.crotti.0@gmail.com> |
|---|---|
| Date | 2011-12-09 12:43 +0000 |
| Message-ID | <mailman.3470.1323434593.27778.python-list@python.org> |
| In reply to | #16875 |
On 12/08/2011 08:17 PM, Catherine Moroney wrote:
> Hello,
>
> Is there a way to create a C-style pointer in (pure) Python so the
> following code will reflect the changes to the variable "a" in the
> dictionary "x"?
>
> For example:
>
> >>> a = 1.0
> >>> b = 2.0
> >>> x = {"a":a, "b":b}
> >>> x
> {'a': 1.0, 'b': 2.0}
> >>> a = 100.0
> >>> x
> {'a': 1.0, 'b': 2.0} ## at this point, I would like the value
> ## associated with the "a" key to be 100.0
> ## rather than 1.0
>
> If I make "a" and "b" numpy arrays, then changes that I make to the
> values of a and b show up in the dictionary x.
>
> My understanding is that when I redefine the value of "a", that Python
> is creating a brand-new float with the value of 100.0, whereas when I
> use numpy arrays I am merely assigning a new value to the same object.
>
> Is there some way to rewrite the code above so the change of "a" from
> 1.0 to 100.0 is reflected in the dictionary. I would like to use
> simple datatypes such as floats, rather than numpy arrays or classes.
> I tried using weakref's, but got the error that a weak reference cannot
> be created to a float.
>
> Catherine
Not sure if it's exactly pure python but Traits can actually do this
https://github.com/enthought/traits
[toc] | [prev] | [next] | [standalone]
| From | alex23 <wuwei23@gmail.com> |
|---|---|
| Date | 2011-12-11 21:45 -0800 |
| Message-ID | <21825f6f-debe-4c9c-8efb-3f1d557cfe8a@d12g2000prg.googlegroups.com> |
| In reply to | #16913 |
Andrea Crotti <andrea.crott...@gmail.com> wrote: > Not sure if it's exactly pure python but Traits can actually do thishttps://github.com/enthought/traits At an attribute level, absolutely, but not at the variable level like the OP is requesting. It's a great package, though :)
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2011-12-10 00:41 +0000 |
| Message-ID | <4ee2aab4$0$29977$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #16875 |
On Thu, 08 Dec 2011 12:17:11 -0800, Catherine Moroney wrote:
> Hello,
>
> Is there a way to create a C-style pointer in (pure) Python so the
> following code will reflect the changes to the variable "a" in the
> dictionary "x"?
Strictly speaking, no, but there may be a way to get something close. See
below.
> For example:
>
> >>> a = 1.0
> >>> b = 2.0
> >>> x = {"a":a, "b":b}
> >>> x
> {'a': 1.0, 'b': 2.0}
> >>> a = 100.0
> >>> x
> {'a': 1.0, 'b': 2.0} ## at this point, I would like the value
> ## associated with the "a" key to be 100.0 ##
> rather than 1.0
The line "a = 100" is a rebinding, and so what you are asking for isn't
directly possible. But if you are willing to live with an explicit
redirection, you can somewhat simulate a pointer with a list:
py> aPtr = [1.0] # not really a pointer, but let's pretend it is
py> bPtr = [2.0]
py> x = {'a': aPtr, 'b': bPtr}
py> x
{'a': [1.0], 'b': [2.0]}
py> aPtr[0] = 100.0
py> x
{'a': [100.0], 'b': [2.0]}
If you prefer, you can write a simple class to handle the redirection
with the interface of your choice. Something like this might be a good
start:
class SharedValue:
def set(self, value):
self.value = value
def get(self):
return self.value
def __repr__(self):
# Somewhat dubious.
return str(self.value)
py> a = SharedValue() # create a pointer
py> a.set(1.0)
py> x = {'a': a}
py> x
{'a': 1.0}
py> a.set(100.0)
py> x
{'a': 100.0}
Look at the automatic delegation pattern for a way to have operations on
"a" automatically apply to the object being pointed to. (This will be
*much* simpler if you don't inherit from object.)
But be warned, whatever you do, rebinding will behave in the standard
Python way. E.g.:
py> aPtr = [2000.0] # Oops, rebound the name to something else!
py> x # and the connection is lost
{'a': [100.0], 'b': [2.0]}
> If I make "a" and "b" numpy arrays, then changes that I make to the
> values of a and b show up in the dictionary x.
Yes, because numpy arrays are mutable objects. In this case, you have two
(or more) references to a single object: the name "a", and the entry in
dict "x". When you modify the object in either place, the change is
visible in both places because they are the same object.
But when you rebind the name "a" to another object -- not necessarily a
*new* object, just a different one -- there is no way for the dict "x" to
notice this change and follow along.
> My understanding is that when I redefine the value of "a", that Python
> is creating a brand-new float with the value of 100.0, whereas when I
> use numpy arrays I am merely assigning a new value to the same object.
Correct. Although the float need not be brand-new. Python could (but
probably doesn't) re-use an existing float object.
--
Steven
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web