main.py:
import subone
import subtwo
subone.py:
a = 'abc'
subtwo.py:
print subone.a
Running python main.py
throws a NameError: name 'subone' is not defined
. I expected it to print 'abc'.
Refactoring it to use from
import
and classes doesn't help:
main.py:
from subone import * # Only using from X import * for example purposes.
from subtwo import *
print 'from main.py:', a.out
subone.py:
class A:
out = 'def'
a = A()
subtwo.py:
# This throws NameError: name 'a' is not defined
print a.out
# This throws NameError: name 'A' is not defined
b = A()
print b.out
BUT it will print 'from main.py: def'. (It works when using import
too.)
Why does it work this way? It seems like once subone
is imported, it should be available to subtwo
.
Is it because it's bad programming to have imported modules depend on each other without going through their 'parent' module? Is there another, standard way to do this?
I now understand that the first example will not work because the line print subone.a
doesn't recognize the name subone
, it not being in subtwo
's namespace (even though it's in main.py
's), and it is being called from within the module subtwo
. This can be fixed by using import subone
at the top of subtwo.py
-- it will not re-load the module but will add it to subtwo
's namespace so subtwo
can use it.
But what about this:
main.py:
from subone import Nugget
from subtwo import Wrap
wrap = Wrap()
print wrap.nugget.gold
subone.py:
class Nugget:
gold = 'def'
subtwo.py:
class Wrap:
nugget = Nugget()
I would think that since Wrap
and Nugget
are both loaded directly into main
's namespace, that they would use main
's namespace and be able to reference each other, but it throws a NameError: name 'Nugget' is not defined
. IS IT because Wrap
is evaluated/checked from within subtwo
's namespace BEFORE being loaded into main
's namespace?
Modules can import other modules. It is customary but not required to place all import statements at the beginning of a module (or script, for that matter). The imported module names, if placed at the top level of a module (outside any functions or classes), are added to the module's global namespace.
This is caused by the fact that the version of Python you're running your script with is not configured to search for modules where you've installed them. This happens when you use the wrong installation of pip to install packages.
Python's ImportError ( ModuleNotFoundError ) indicates that you tried to import a module that Python doesn't find. It can usually be eliminated by adding a file named __init__.py to the directory and then adding this directory to $PYTHONPATH .
So each module is imported only one time. To better understand import mechanics I would suggest to create toy example. So import really happens only once. You can adjust this toy example to check cases that are interesting to you.
If you modified your subtwo.py this way then it will work
import subone
print subone.a
When you do subone.a in subtwo.py, you are trying to access the namespace subone in subtwo.py and in the namespace "subone", there should be a attribute "a".
When you do - import subone in subtwo.py, then subone is added to the namespace and subone namespace has attribute a. so subone.a will work.
I would also suggest that you play with dir() to see how namespaces are being added.
In subtwo.py, you can do the following:
print dir()
import subone
print dir()
print subone.a
Similarly, try adding "print dir()" before and after your import statements and the idea should become clear to you.
"import x" adds 'x' to the current modules namespace while "from x import * " will add all the module level attributes directly into current module namespace
So in your above first example of main.py, subone.py and subtwo.py, the namespace in main.py will contain 'subone' and 'subtwo' while subtwo.py will have an empty namespace and can not access subone.a.
[Edit: Some more explanations] Consider following files: main.py
print "Before importing subone : ", dir()
import subone
print "After importing subone and before importing subtwo: ", dir()
import subtwo
print "After importing subone and subtwo: ", dir()
subone.py
a = 'abc'
subtwo.py
print dir()
import subone
print "module level print: ", subone.a
print dir()
def printX():
print subone.a
And the output of running main.py:
Before importing subone : ['__builtins__', '__doc__', '__file__', '__name__', '__package__']
After importing subone and before importing subtwo: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'subone']
['__builtins__', '__doc__', '__file__', '__name__', '__package__']
module level print: abc
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'subone']
After importing subone and subtwo: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'subone', 'subtwo']
Some Observations
Can you explain why you feel like subone should be available to subtwo, when subone has been imported by main? As it is, subtwo.py can be compiled without knowing what main.py has imported.
Also, if a second program imports subtwo.py, should subtwo's knowledge of subone depend on which of two main programs is importing subtwo? This would reduce reusability of subtwo.
It seems like you're thinking of the compilation as a process with a defined order, accumulating state information: compile main.py, during which we compile/import subone.py, accumulating information from it, and then we compile/import subtwo.py, using the information we've already accumulated.
Instead, the compilation of each module is independent of others, unless dependencies are declared. This makes it much easier to reuse and maintain code: there are fewer hidden dependencies.
Is it because it's bad programming to have imported modules depend on each other without going through their 'parent' module?
Not as such... It's just bad programming to have module 2 depend on module 1 without saying so, i.e. without module 2 declaring "I depend on module 1".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With