[Tutor] Perl vs. Python's way of handling references.

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Fri Apr 11 17:02:02 2003


> This does not work as expected. Chage the value of the variable one and
> you don't change the value of dict['a']:
>
> >>> one = 1
> >>> two = 2
> >>> my_dict = {'a':one,'b':two}

Hi Scott,

This is an interesting topic!  It might help to see what this is actually
doing, by drawing a simplified picture of our program's universe.  Here's
what it might look like to ASCII people:


                                       my_dict
                                         |
                                         |
                                         v
                                      +--------------+
                                      |              |
    one--------------->  1  <---------|-my_dict['a'] |
                                      |              |
                                      |              |
    two--------------->  2  <---------|-my_dict['b'] |
                                      |              |
                                      +--------------+



That is, 'one' and 'two' are names that refer to some integer objects.
Assignment is an action that gets a name to point to an object.  my_dict
itself is a container, and we see that my_dict['a'] and mydict['b'] also
refer to those same integer objects.


Ok, let's go through a few more statements.

###
> >>> my_dict['a']
> 1
> >>> one = 3
###



At this point, we assign 'one' to a new integer object, so our diagram has
changed.  Let's see what it might look like:


                                       my_dict
                                         |
                                         |
                   +-->  3               v
                   |                  +--------------+
                   |                  |              |
    one------------+     1  <---------|-my_dict['a'] |
                                      |              |
                                      |              |
    two--------------->  2  <---------|-my_dict['b'] |
                                      |              |
                                      +--------------+


When we compare against the original diagram, we can notice that when we
say:

    one = 3

we redirect the name 'one' to point to 3.  The key thing to see, however,
is that we don't change the arrow that my_dict['a'] points to: it still
points to 1.  And we see that this is true:


###
> >>> my_dict['a']
> 1
###




> The id()'s show that dict['a'] is not pointing to the variable one but
> to it's value, 1.  This is one of the unique things python does with
> it's namespaces.

This isn't really about namespaces: it's more about seeing what variable
names are, and what assignment means.  If we want, we can "adding a level
of indirection", so that it looks like changes to 'one' reflect to changes
in 'my_dict'.



We can make our system look like this:


                                       my_dict
                         1               |
                         ^               |
                         |               |
                         |               v
                         |            +--------------+
                       +---+          |              |
    one--------------->| | |<---------|-my_dict['a'] |
                       +---+          |              |
                                      |              |
    two--------------->  2  <---------|-my_dict['b'] |
                                      |              |
                                      +--------------+


I'm using boxes to symbolize "mutable" containers.  This diagram shows
that we can make 'one' and my_dict['a'] refer to a list.

###
>>> one = [1]
>>> two = 2
>>> my_dict = {'a' : one, 'b' : two}
>>> one[0] = 3
>>> one
[3]
>>> two
2
>>> my_dict
{'a': [3], 'b': 2}
###


Is this the effect that you are looking for?


Please feel free to ask questions about this.  Good luck!