globals( ) and binding doubt (newbie) !

Robin Munn rmunn at pobox.com
Tue Jan 8 12:55:08 EST 2002


On Tue, 8 Jan 2002 10:21:55 -0500, Steve Holden <sholden at holdenweb.com> wrote:
>"Karthik Gurumurthy" <karthikg at aztec.soft.net> wrote in message
>news:mailman.1010502130.4654.python-list at python.org...
>> Can someone tell me why it did'nt use the correct versions of the
>functions
>> earlier.
>> When python comes across a name, it does look up in locals() or globals()
>> and then executes the
>> one mapped there?
>>
>Yes, at a first approximation. But your code isn't using names, it's using
>function references stored in a list before the names were rebound.
>
>> When i redefined f1 , f2 and f3, globals would have accepted these and
>> overwritten the earlier one?
>>
>>
>They did overwrite the earlier ones, but that didn't change the bindings of
>the elements of seq - that change only took place with your second
>assignment to seq.
>
>> thanks for your patience!
>
>Hope this clarifies things for you.

Let me put my own explanation in here and see if it simplifies or
complicates matters. I like to think of names as "pointers" to the real
objects. When Python comes across an assignment, it creates a new name
or re-uses an old one and has it point to a certain object. Like so:

----- code -----

class Thing:
    def __init__(self, num):
	self.value = num

a = Thing(1)
b = Thing(2)

----- end code -----

Now we have two names and two objects:

+-+              +-+
|a|  --------->  |1|
+-+              +-+

+-+              +-+
|b|  --------->  |2|
+-+              +-+


Now if we do:

----- code -----

c = b

----- end code -----

We end up with:

+-+              +-+
|a|  --------->  |1|
+-+              +-+

+-+              +-+
|b|  --------->  |2|
+-+           -> +-+
             /
+-+         /
|c|  -------
+-+


Next we do this:

----- code -----

b = a

----- end code -----

And the result is:

+-+              +-+
|a|  --------->  |1|
+-+           -> +-+
             /
+-+         /    +-+
|b|  -------     |2|
+-+           -> +-+
             /
+-+         /
|c|  -------
+-+

Note that c does *not* change.


Then if we do:

----- code -----

a = Thing(3)

----- end code -----

We obtain:    -------
             /       \
+-+         /    +-+  \
|a|  -------     |1|   |
+-+           -> +-+   |
             /         |
+-+         /    +-+   |
|b|  -------     |2|   |
+-+           -> +-+   |
             /         |
+-+         /    +-+  / 
|c|  -------     |3|<-
+-+              +-+



Does that help? I always like to draw diagrams when I'm trying to figure
something out, as I find it helps me see the relationships better.

In the case of your example (which I snipped most of so that this post
wouldn't grow unwieldy), what was happening is that the names f1, f2 and
f3 were pointing to certain function objects initially. Then you stored
some more pointers to those objects in a list (kind of like "b = a" in
my example above). Then you redefined what f1, f2 and f3 were pointing
to (like the "a = Thing(3)" line) but that didn't change the pointers
that had already been stored in the list. Remember, it's never the
*name* that gets pointed to, but always the *object*.

-- 
Robin Munn
rmunn at pobox.com



More information about the Python-list mailing list