Where is my namespace?

Bruno Desthuilliers bruno.42.desthuilliers at websiteburo.invalid
Mon Dec 7 11:38:46 EST 2009


vsoler a écrit :
> 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.

It's "amazing" only if you believe Python's "global" scope is really 
global. Thruth is that in Python, "global" means "module-level" - so 
when you call printer, it resolves X in it's own "global" namespace - 
that is, nested1's global namespace.

> My questions are:
> 
> 1. Using statement "from" instead of "import" should not create a
> namespace,

It doesn't.

> at least that's what I think. However, the printer()
> function is able to find 99 which is residing in...  a namespace?

Yes, cf above. This namespace is created when the nested1.py module is 
first loaded (whether via any form of import or via direct execution of 
nested1 as a script).

> 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

You have to import the nested1 module itself, ie:

# nested3.py
import nested1

print nested1.X
printer()
nested1.X = 42
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?

Think of Python's namespaces as dicts, where names are keys and 
reference to objects are values.

If you do:

   import nested1

then your current namespace will look like :

   {"nested1" : <module 'nested1' from /path/to/nested1.py>}

But if you do:

   from nested1 import printer

Then your namespace will look like:

   {"printer" : <function 'printer'>}


Of course, in this case, the name "printer" in the current namespace is 
bound to the same function object as nested1.printer - but the _name_ 
"printer" is local to your current namespace. If you rebind this name in 
the current namespace, it wont affect nested1's namespace.

HTH



More information about the Python-list mailing list