1

I am kind of confused on what the import statements does in python so to understand that i have this sample test.py script:

def functionA():
    import test
    print("a1")

def functionB():
    print("b")

print("t1")
functionA()
print("m1")

When i execute this test.py script using the following command: python3 test.py I get the following:

t1
t1 
a1 
m1 
a1 
m1

It would be great if someone can explain to me why i get the following output and what exactly is happening.

  • 1
    Can you please clarify what parts of ``import`` you understand? What output you would have expected instead? Why are you confused by the output you get? – MisterMiyagi May 25 '20 at 16:10
  • @MisterMiyagi What does the statement import test do? I was expecting that everytime functionA() is called then it is going to call the script again, executing the script infinitely. – Yousif Dafalla May 26 '20 at 03:08
  • I've added an answer to what ``import test`` does, and why it seemingly imports the module twice (but not more). – MisterMiyagi May 26 '20 at 07:06

2 Answers2

3

The flow of execution is a little hard to understand. But here it is

When you execute your file using python3 test.py it executes the script whose first line generates t1

Now it calls functionA() which imports your script(so executing your script second time) which gives t1 then it calls functionA() again but this time test is already imported so the next line of execution is a1. then we execute line 3 which gives m1. Now we come outside the functionA()'s (first call) import and execute a1

and then we exit first functionA() call and print m1

For more info refer this link

lorem_bacon
  • 165
  • 1
  • 10
  • 2
    It might be worth explaining *why* the module gets executed a second time - something that ``import`` usually does not do. – MisterMiyagi May 25 '20 at 16:11
  • Thanks for the advice. I have added a link for the topic. – lorem_bacon May 25 '20 at 17:03
  • @PrashantNegi if `import test` executes the script how come functionA() doesn't execute infinitely? I was expecting the program to never terminate and keep executing itself. What makes it terminate? – Yousif Dafalla May 26 '20 at 03:12
  • @YousifDafalla First time **import** is called it register the module/file in the namespace, so if it is already present there(on second call to import), python basically ignores the import – lorem_bacon May 26 '20 at 04:22
0

TLDR: import loads each module only once per interpreter session. However, the main module is special in that it can be imported in two variants.


The import statement is responsible for two things:

  • loading the target module into the interpreter, and
  • binding the module or some of its name in the current scope.

Notably, if the module has already been loaded (it is in sys.modules), the module is not loaded again. Only the name binding happens in this case.

This is why importing the module recursively does not rerun its code infinitely.


The main module, that is the initial module run, is special in that it can regularly exist with two variants:

  • with the name __main__, set automatically by running the module, and
  • with its own name such as test, set automatically by importing the module.

Notably, these two versions are not identical. Every module with an if __name__ == "__main__": guard runs different code, and thus achieves different state.

This is why the __main__ module can be loaded twice, once under the name __main__ and once under its own name.


For this code in specific, the sequence is like this:

  • Executing python3 test.py sets up test.py to be imported as __main__.
  • There is no module __main__ yet. Python executes test.py to create the module.
    • functionA and functionB are defined,
    • print("t1") is called,
    • functionA is called,
      • import test is run,
        • There is no module test yet. Python executes test.py to create the module.
          • functionA and functionB are defined,
          • print("t1") is called,
          • functionA is called,
          • import test is run,
            • The module test already exists (though not completely).
            • Python binds the test module to the name test.
          • print("a1") is called,
        • print("m1") is called,
      • print("a1") is called,
    • print("m1") is called,
MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119