faqts : Computers : Programming : Languages : Python : Common Problems

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

9 of 9 people (100%) answered Yes
Recently 5 of 5 people (100%) answered Yes

Entry

How come the global declaration works when I define it from within the interpreter, but not from within a file that I import?

May 31st, 2000 06:03
unknown unknown, Curtis Jensen, Emile van Sebille, David Goodger


Example:

file: foo_bar.py:
def foo(i):
  x = i

def bar(i):
  global y
  y = i

Python interpreter:
>>> from foo_bar import *
>>> bar(0)
>>> print y
Traceback (innermost last):
  File "<stdin>", line 1, in ?
NameError: y
>>> def other(i):
...   global z
...   z = i
...
>>> other(5)
>>> print z
5
>>> ^D

Solution:

Your 'y' variable exists at the module level in foo_bar.

See section 4.1 in the Python Refernce Manual the explains namespaces.

Also, from import * can be dangerous as it replaces references in the
current namespace.  

>>> bar(3)
>>> foo_bar.y
3
>>> 

----------

Because global means "global at the module level". There is no sharing 
of globals between modules (if there were, what chaos that would 
create!). When you're working in the interactive interpreter, you are 
actually in the "__main__" module's namespace. When you import a module 
(regardless of whether you use "import x" or "from x import *"; the 
latter just copies all of x's names into the current namespace), you 
create a new namespace for that module. Any global variables created by 
that module are global within that module's namespace. For example, 
assume file mytest.py contains:

    def spam(i):
        global x
        x = i

So "x" will be global in mytest's namespace, rather than just local to 
the spam() function.

Now let's test it:

    >>> from mytest import *
    >>> spam(5)
    >>> x
    Traceback (innermost last):
      File "<input>", line 1, in ?
    NameError: x

This is as you saw. Now, let's "import sys". "sys.modules" is a 
dictionary contining all imported modules, indexed by name:

    >>> import sys
    >>> sys.modules["mytest"]
    <module 'mytest' ...>
    >>> sys.modules["mytest"].x
    5

So x *was* changed, in mytest's global namespace, but not __main__'s.

When you define a function in the interpreter:

    >>> def eggs(i):
    ...     global z
    ...     z = i
    >>> eggs(5)
    >>> z
    5

The function "eggs()" is defined in the "__main__" module, in __main__'s
namespace, therefore "global z" makes z a global variable in __main__'s
namespace.