Where is my namespace?

Benjamin Kaplan benjamin.kaplan at case.edu
Mon Dec 7 11:39:06 EST 2009


On Mon, Dec 7, 2009 at 11:10 AM, vsoler <vicente.soler at gmail.com> wrote:
> I take the example from Mark Lutz's excellent book "Learning Python".
>
> *** In nested1.py  I have:
> X=99
> def printer(): print X
>
> *** In nested2.py  I have:
> from nested1 import X, printer
> X=88
> printer()
>
> What is amazing is that running nested2.py prints 99 and not 88.
>
> My questions are:
>
> 1. Using statement "from" instead of "import" should not create a
> namespace, at least that's what I think. However, the printer()
> function is able to find 99 which is residing in...  a namespace?
>

It doesn't create a namespace. But printer is still in nested1. When
you do a "from ... import ...", the objects are imported into the
current namespace. However, they are different names for what is
currently the same object. They still follow Python's object
semantics. Here's a simplified overview of what happens

you run nested2.py

1 namespace: nested2, nothing in it (except for the special stuff)

you run "from nested1 import X, printer". This executes everything in
nested1 (because def and class are just executable statements in
Python) and binds X and printer in nested2 to the objects in nested1.
Note that these are now different names for the same objects.

nested1: X = 99, printer = <function in nested1>
nested2: X = 99 printer = <function in nested1>

you call X = 88. Because you are rebinding the object, this name
(nested2.X) is the only one that gets changed. Rebinding doesn't touch
the object in nested1.

nested1: X=99, printer = <function in nested1>
nested2: x=88 printer = <function in nested1>

Notice how the name "printer" in nested2 still refers to an object in
nested1. It is simply another reference, not a new object. When you
call printer, it's still sitting in nested1 and only sees nested1's X.

> 2. I have tried to access the 88 by qualification from nested2.py.
> However, I cannot. If using "print nested1.X" in nested2.py I get an
> error

that's because when you do "from ... import ..." it doesn't import the
module itself. There's a totally different behavior between from ...
import and import. Here's what you're trying to do

nested2.py :

import nested1

nested1.X = 88
nested1.printer()

>
> 3. Mark says: The from statement is really an assignment to names in
> the importer's scope--a name-copy operation, not a name aliasing.   I
> don't fully understand what he means. Could anybody explain?
>

Like I showed before, when you change the unqualified "X" in nested2,
the X in nested1 doesn't change. Using from import is identical to
doing something like this

a = 1
b = a
b = 5
a == 1 #True

a is a name that temporarily referred to the same object as a.
However, when you reassign b, it makes the name "b" refer to a
different object. It doesn't change the object that a and b both refer
to. When you import using  from ... import, you end up with 2
different names that, at the start refer to the same object. Mutation
(if you're using a mutable object) will show up in both namespaces,
since they are referring to the same object, but assignment does not.

> Thank you very much for your time.
>
> Vicente Soler
> --
> http://mail.python.org/mailman/listinfo/python-list
>



More information about the Python-list mailing list