Namespaces with Module Imports
"Explicit is better than implicit" is a design decision that was made by the creators of Python (launch python and run import this
).
Therefore, when you run module1.cool()
, Python will not look for the undefined pi
in the main
module.
You'll have to import the math module in explicitly whenever you want to use it - that's just how Python works.
Also, you should avoid from X import *
-style imports, that's bad practice too. Here, you could do: from math import pi
.
As the traceback shows, the problem isn't in main.py
, but in module1.py
:
Traceback (most recent call last):
File "Z:\Python\main.py", line 10, in <module>
module1.cool()
File "Z:\Python\module1.py", line 3, in cool
print pi
NameError: global name 'pi' is not defined
In other words, in module1
, there is no global name pi
, because you haven't imported it there. When you do from math import *
in main.py
, that just imports everything from the math
module's namespace into the main
module's namespace, not into every module's namespace.
I think the key thing you're missing here is that each module has its own "global" namespace. This can be a bit confusing at first, because in languages like C, there's a single global namespace shared by all extern
variables and functions. But once you get past that assumption, the Python way makes perfect sense.
So, if you want to use pi
from module1
, you have to do the from math import *
in module1.py
. (Or you could find some other way to inject it—for example, module1.py
could do from main import *
, or main.py
could do module1.pi = pi
, etc. Or you could cram pi
into the magic builtins
/__builtin__
module, or use various other tricks. But the obvious solution is to do the import
where you want it imported.)
As a side note, you usually don't want to do from foo import *
anywhere except the interactive interpreter or, occasionally, the top-level script. There are exceptions (e.g., a few modules are explicitly designed to be used that way), but the rule of thumb is to either import foo
or use a limited from foo import bar, baz
.