Reputation: 2067
I have two modules as follows:
Module A - moda.py
import modb
x = None
def printx():
global x
print(x)
def main():
global x
x = 42
printx()
modb.printx()
printx()
if __name__ == '__main__':
main()
Module B - modb.py
import moda
def printx():
moda.printx()
print('modb imported')
When I run python moda.py
, the output I get is:
modb imported
42
None
42
I don't understand why the second print (coming from modb.printx()) is None. I thought python modules behaved as singletons. What am I missing?
Can someone please explain why the module imported in modb
is not same as the original module moda
?
Upvotes: 3
Views: 82
Reputation: 114320
When an import
statement is encountered, the interpreter looks for a corresponding key in sys.modules
. If a key is found, it is bound to the name you requested. If not, a new empty module object is createdplaced in sys.modules
, , and then populated. The reason for doing it like that is exactly to avoid infinite loops with circular imports.
When you run a module, it is imported under the name __main__
. You ca
Here is the sequence of events when you run moda
as a script:
moda.py
as sys.modules['__main__']
. At this point, this is just an empty namespaceimport modb
encountered in moda.py
. New empty namespace created for sys.modules['modb']
.import moda
encountered in modb.py
. New empty namespace created for sys.modules['moda']
. Notice that this is not the same object as sys.modules['__main__']
in step 1.import modb
encountered in moda.py
. Since sys.modules['modb']
exists, it is bound to that name in moda
moda.py
is currently being loaded under the name moda
, it finishes populating its namespace without running the import guard.modb.py
finishes populating its namespace (from step 2.) and runs print('modb loaded')
.__main__
defined in moda.py
finishes populating its namespace (from step 1.) and runs the import guard.Hopefully this helps you visualize what happens. You have three modules, not two, that were loaded, because moda
is loaded under two different names, and as two entirely different module objects.
The import guard in __main__
calls __main__.main
, which does the following:
__main__.x = 42
(moda.x
is still None
)__main__.printx
prints __main__.x
, which is 42
modb.printx
calls moda.printx
, which prints moda.x
, which is None
.__main__.printx
prints __main__.x
again, which is still 42
.Upvotes: 3