Why I need to declare import as global in function

Rick Wotnaz desparn at wtf.com
Wed Nov 30 13:21:08 EST 2005


Dennis Lee Bieber <wlfraed at ix.netcom.com> wrote in
news:tmmro191j33lbep1i04pn3a2lcsll9fgt6 at 4ax.com: 

> On 30 Nov 2005 00:58:45 -0800, didier.doussaud at gmail.com
> declaimed the following in comp.lang.python:
> 
>> yes I have imported math in the file I want to use it. But the
>> imported module "math" is not visible in function without a
>> global instruction. 
>> 
>      The code you just posted shows it, yes... My reading of an
>      earlier 
> message seemed to imply you had a nested import chain with the
> "import math" at the wrong level... Something like:
> 
> #file 1
> execfile("file 2")
> 
> #file 2
> import math
> import file_3
> 
> #file_3
> print math.pi
> 
>> But the solutions already proposed seems to work file for my
>> sample program. I will try on my project soon :)
> 
>      Looking at the documentation for "execfile", I can see
>      /how/ the 
> problem occurs -- but can't determine if this can be considered
> "expected".
> 
> -=-=-=-=-=-=-
> execfile( filename[, globals[, locals]]) 
> 
> This function is similar to the exec statement, but parses a
> file instead of a string. It is different from the import
> statement in that it does not use the module administration --
> it reads the file unconditionally and does not create a new
> module.2.2 -=-=-=-=-=-=-
> 
>      I'm guessing that the intent was only that "file 1" not
>      become an 
> entry on the module list, but it seems to be applying "...not
> create a new module" recursively to the imported "math"... Maybe
> an expert with the Python byte-code can verify. My hypothesis is
> something on the order of:
>      Outer (file level) references to math (math.pi) are being
>      handled 
> during the byte-code compilation phase of execfile, so even if
> "math" isn't in the module list, it is still in local scope for
> the outer math.pi...
> 
>      Inner (function) references to math become dynamic look-ups
> evaluated at function execution; at that point math is not in
> scope and is not in the module list.
> 
>      Interestingly, I note that is the file calling execfile has
>      imported 
> math (so math is in the module list), the called file works...
> 
> #no import in run
> E:\UserData\Dennis Lee Bieber\My Documents\Python Progs>python
> run.py in module:       <module 'math' (built-in)>
> Traceback (most recent call last):
>   File "run.py", line 5, in ?
>     run_ut("ut_00.py")
>   File "run.py", line 3, in run_ut
>     execfile(test)
>   File "ut_00.py", line 8, in ?
>     f()
>   File "ut_00.py", line 5, in f
>     print "in function: \t %s" % math
> NameError: global name 'math' is not defined
> 
> #import is in run
> E:\UserData\Dennis Lee Bieber\My Documents\Python Progs>python
> run.py <module 'math' (built-in)>
> <module 'math' (built-in)>
> in module:       <module 'math' (built-in)>
> in function:     <module 'math' (built-in)>
> 

This may be saying what you said, but it seems to depend on where 
the import occurs:
# File: runt2.py
def Bobo():
    import math
    execfile( "ut_00.py" )
b = Bobo()

>runt2
First access :
        3.14159265359
Second access :
        Traceback (most recent call last):
  File "D:\pyWork\test\runt2.py", line 5, in ?
    b = Bobo()
  File "D:\pyWork\test\runt2.py", line 3, in Bobo
    execfile( "ut_00.py" )
  File "ut_00.py", line 10, in ?
    f()
  File "ut_00.py", line 6, in f
    print "\t",math.pi # ERROR
NameError: global name 'math' is not defined

# File: runt.py
import math
def Bobo():
    execfile( "ut_00.py" )
b = Bobo()

>runt
First access :
        3.14159265359
Second access :
        3.14159265359

So the import at the module level of the caller works, but an 
import at the function level of the caller doesn't. I don't see why 
the namespace would be significantly different by the time execfile 
is executed, though it apparently is.

-- 
rzed



More information about the Python-list mailing list