references / aliases in Python
sholden at holdenweb.com
Wed Jan 15 15:02:57 CET 2003
"Jonathan P." <jbperez808 at yahoo.com> wrote in message
news:f57664b9.0301141544.1f797188 at posting.google.com...
> I couldn't exactly follow Steve Holden's example:
> function(args).dict[index][index].a = 21
> function(args).dict[index][index].b = 42
> function(args).dict[index][index].c = 63
> But the idea of references did get through because I was
> trying to do something similar. I was wondering if there
> was a way to get true references in Python ala below:
Well I'm not sure that was *MY* example (though there's a CVS repository
which would force me to confess if it proved to be the case).
However, basically what it's trying to say is that you can use a name bound
to an object to speed up references to attributes of that object. In the
case you quote, the object is function(args).dict[index][index], and the
point is that Python, which uses few optimizations to speed up compiled
code, will cheerfully go through the exact same sequence of operations three
times to determine the same object, whose "a", "b" and "c" attributes are
required by the code.
So, it's a win to bind a name to the object and then qualify that name to
get the attributes of the object.
> >>> class A:
> def __init__(self):
> def f1(self):
> ref1=&self.long_descriptive_name1 # hypothetical address-of
> if (*ref1)>(*ref2)+1: (*ref1)=(*ref2)
> # hypothetical dereference operator
> replacing the long and rather unreadable (in practice it often
> gets much worse than shown below):
> if self.long_descriptive_name1>self.long_descriptive_name2+1:
> Is there a way to get aliases without having to add a pointer
> type + referencing / dereferencing operators to Python? What
> exactly is the Python philosophy regarding pointer types and
> referencing / dereferencing?
Unfortunately this requirement is the other way around. If the
long_descriptive_names refer to objects whose attributes are required then
you can use the trick from the FAQ. Otherwise you are hosed: if two names
are bound to the same immutable value, changing the value of one leaves the
names referring to different objects.
With mutable objects the position is a little better: modifying a mutable
object to which multiple namesa re bound leaves each name still referring to
the same object. However, you then need to take care with augmented
assignments (such as +=) because there the language lets the object
implementation decide whether the operation is implemented as an in-place
update (giving the latter behavior) or as the creation of a new object
(giving the former behavior).
The Python philosophy regarding poiner types is simple: there aren't any.
Names are references to values. Attributes of objects are references to
values. Elements of dictionaries, lists and tuples are references to values.
Values do not have names, they are simply bound by assignment (to names,
attributes of objects, or elements of dictionaries, lists and tuples). Each
value (object) has an associated reference counter, incremented and
decremented automatically as references are created and destroyed. When an
object's reference count reaches zero it becomes a candidate for garbage
collection. Special features allow collection of "cyclic garbage" to handle
the cases where a set of objects refer only to each other.
Hope this helps.
Steve Holden http://www.holdenweb.com/
Python Web Programming http://pydish.holdenweb.com/pwp/
Bring your musical instrument to PyCon! http://www.python.org/pycon/
More information about the Python-list