By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,143 Members | 1,908 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,143 IT Pros & Developers. It's quick & easy.

Why I need to declare import as global in function

P: n/a
I have a stange side effect in my project :

in my project I need to write "gobal" to use global symbol :

....
import math
....
def f() :
global math # necessary ?????? else next line generate an error
message ?????
print math.pi

(the problem is for all global module symbol)

I have certainly change somthing in my project, but I can't find what ?

(just a small program wort fine without this global of course)

Can anybody help me : where can I search the mistake in my project ?

Nov 28 '05 #1
Share this Question
Share on Google+
16 Replies


P: n/a
Sounds like something, either in your program, in another lib you
imported, or perhaps some extension you recently installed (and which
automatically starts), overrides 'import' (replaces it with it's own
version) -- and forgets to add the imported modules properly to the
globlals?
Or something, some option, that perhaps changes the way that Python
recognizes globals?

If you declare another global variable, then try to use it in your
function, then what's the result?

What Python version do you use?

cheers,

--Tim

Nov 28 '05 #2

P: n/a
di*************@gmail.com wrote:
I have a stange side effect in my project :

in my project I need to write "gobal" to use global symbol :

...
import math
...
def f() :
global math # necessary ?????? else next line generate an error
message ?????
what error message?
print math.pi


you only need global in this case if you assign to the name somewhere
later in the function (e.g. "math = ..." or "import math" or some other
assignment)

please post the error message (the entire traceback).

</F>

Nov 28 '05 #3

P: n/a
the error message :

EXCEPTION RAISED::

Traceback (most recent call last):
File "../tu.py", line 21, in run_tu
execfile( filename )
File "TU_05_010.py", line 8, in ?
import TU_05_tools
File "./TU_05_tools.py", line 4, in ?
f()
File "./TU_05_tools.py", line 2, in f
print math.pi
NameError: global name 'math' is not defined

I have remarq that this problem is raised when I execute code in an
imported module (during importation)

I think I will be able to isolate it and have a simple sample soon ....

Nov 29 '05 #4

P: n/a
wrote:
I have remarq that this problem is raised when I execute code in an
imported module (during importation)

I think I will be able to isolate it and have a simple sample soon ....

Meanwhile, try adding:

import math

to the top of TU_05_tools.py.
Nov 29 '05 #5

P: n/a
di*************@gmail.com wrote:
the error message :

EXCEPTION RAISED::

Traceback (most recent call last):
File "../tu.py", line 21, in run_tu
execfile( filename )
File "TU_05_010.py", line 8, in ?
import TU_05_tools
File "./TU_05_tools.py", line 4, in ?
f()
File "./TU_05_tools.py", line 2, in f
print math.pi
NameError: global name 'math' is not defined

I have remarq that this problem is raised when I execute code in an
imported module (during importation)

I think I will be able to isolate it and have a simple sample soon ....


Random guess: change the execfile() call to

execfile(filename, globals())

or

exec file(filename).read()

If one of the above works, a minimal example of what happens could be

file("tmp.py", "w").write("""
import math
""")

def f():
execfile("tmp.py")
print locals()["math"].pi # 3.14159265359
print math.pi # Error, math looked up in the global
namespace

f()

execfile() puts symbols into the local namespace but keeps the compiler
clueless because it's just an ordinary function, whereas exec triggers the
generation of slightly different bytecode for the enclosing function.

Peter

Nov 29 '05 #6

P: n/a
Peter Otten wrote:
Traceback (most recent call last):
File "../tu.py", line 21, in run_tu
execfile( filename )
File "TU_05_010.py", line 8, in ?
import TU_05_tools
File "./TU_05_tools.py", line 4, in ?
f()
File "./TU_05_tools.py", line 2, in f
print math.pi
NameError: global name 'math' is not defined

I have remarq that this problem is raised when I execute code in an
imported module (during importation)

I think I will be able to isolate it and have a simple sample soon ....


Random guess: change the execfile() call to

execfile(filename, globals())

or

exec file(filename).read()


That is unlikely to help. The execfile target seems to have been
TU_05_010.py, but the file which cannot access math is TU_05_tools.py
accessed by a normal import, so adding some globals to the execfile call
won't really do anything useful.

Isn't it fun trying to guess the problem in the absence of the code?
Nov 29 '05 #7

P: n/a
Duncan Booth wrote:
Isn't it fun trying to guess the problem in the absence of the code?


What other reason could there be to forego the sane approach -- stick
'import math' everywhere it might belong?
Those exec/execfile() peculiarities are so much more interesting ;-)

Peter

Nov 29 '05 #8

P: n/a
Duncan Booth wrote:
That is unlikely to help. The execfile target seems to have been
TU_05_010.py, but the file which cannot access math is TU_05_tools.py
accessed by a normal import, so adding some globals to the execfile call
won't really do anything useful.

Isn't it fun trying to guess the problem in the absence of the code?


given that the NameError occurs on line 2 of the file, inside a function, this
is probably just a misunderstanding of how namespaces work in Python...

</F>

Nov 29 '05 #9

P: n/a
You're right, the problem is around the usage of "execfile".

But I have still difficulties to get a simple sample.... and have no
enough time to work on it until end of week.

I will post if I resolve my problem or if I can get a simple sample.

Nov 29 '05 #10

P: n/a
I think I understand my problem, but first the sample code extracted to
my project.

Rq : it's an automatic run of unitary test, the names of unitary test
are parameter of main program "imported" file via the "execfile"
function (an usage of "import" instead may be a solution....) :

file run.py :
----------------

def run_ut( test ) :
# to have the problem the execfile MUST be in a function
execfile( test )
run_ut( "ut_00.py" )
file ut_00.py :
--------------------
import math

def f() :
## global math # <-- just decomment this line to avoid error
print "Second access :"
print "\t",math.pi # ERROR

print "First access :"
print "\t",math.pi # OK
f()

Nov 30 '05 #11

P: n/a
lot's of solutions proposed in the discussion works fine :

file run.py :
----------------
def run_ut( test ) :
# to have the problem the execfile MUST be in a function
# execfile( test ) # ERROR
execfile( test, globals() ) # OK
exec "import ut_00" # OK
exec file(test).read() # OK
run_ut( "ut_00.py" )

Thanks a lor

Nov 30 '05 #12

P: n/a
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.

But the solutions already proposed seems to work file for my sample
program. I will try on my project soon :)

Nov 30 '05 #13

P: n/a
sample and solution posted in another branch of this thread....

Nov 30 '05 #14

P: n/a
di*************@gmail.com wrote:
I think I understand my problem, but first the sample code extracted to
my project.

Rq : it's an automatic run of unitary test, the names of unitary test
are parameter of main program "imported" file via the "execfile"
function (an usage of "import" instead may be a solution....) :

file run.py :
----------------

def run_ut( test ) :
# to have the problem the execfile MUST be in a function
execfile( test )
run_ut( "ut_00.py" )
file ut_00.py :
--------------------
import math

def f() :
## global math # <-- just decomment this line to avoid error
print "Second access :"
print "\t",math.pi # ERROR

print "First access :"
print "\t",math.pi # OK
f()


How interesting. Can anyone actually explain the behaviour here?

Without the global statement everything works as I expect: the 'import
math' is executed in the local scope of run_ut, so the function f() doesn't
find it either in its local scope nor in global scope.

Inserting 'global math' at the outer level in ut_00.py (e.g. before the
'import math') also works as I expect: math now becomes a global variable
and is visible to f().

What I really don't understand is why the global statement *inside* f
affects the scope of math outside f. If we had nested functions then a
global variable in an inner function doesn't affect scope in outer
functions. I realise that f() here isn't a nested function, but even so it
looks to me like a bug unless I'm missing something.

(Technically the program is invoking undefined behaviour as the language
reference says that names listed in a global statement must not be defined
in an import statement, but that isn't really relevant since you can
replace the import with an assignment statement and get the same weird
behaviour.)
Nov 30 '05 #15

P: n/a
Dennis Lee Bieber <wl*****@ix.netcom.com> wrote in
news:tm********************************@4ax.com:
On 30 Nov 2005 00:58:45 -0800, di*************@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
Nov 30 '05 #16

P: n/a
Dennis Lee Bieber wrote:
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...


the byte code is identical for both cases; the only difference I can see is
that when when you compile a function that contains a global statement,
the corresponding name is added to the globals for the function that does
the compilation (run_ut in this case).

if you don't use globals, or if the "global" name doesn't exist in the module
namespace, this doesn't happen.

hmm. puzzling.

</F>

Nov 30 '05 #17

This discussion thread is closed

Replies have been disabled for this discussion.