Quan Zhou
Quan Zhou

Reputation: 327

Python scopes and namespaces of imported modules

I am confused on how scopes and namespaces are determined in Python. Assuming I have a file system as following:

|-test1.py
 -test2.py

Each files is defined as below:

test1.py:

#!/usr/bin/python
def test1():
    print('test1')

test2.py:

#!/usr/bin/python
from test1 import test1
def test2():
    test1()
    print('test2')

In python interactive interpreter, if I do the following:

import test2
test2.test2()

, the code would run fine and give following result:

test1
test2

From the output, we can see the interpreter can correctly identify the test1() function object. What confuses me is when test1.test1 is imported during the execution? When this object goes into global scope?

Based on @Ziyad Edher answer, I have created a Venn diagram to illustrate the relationship of different scopes. Assumed the interpreter is replaced by a third file test3.py. Their scopes are as following: The circle represent the scope, the File test3 refers to the test3.py, File test2 refers to test2.py, test2() refers to the function test2() in the test2.py, test1() refers to the function test1() in the test1.py. The scope of test2() does not have test1(), so the interpreter would refer to a upper level scope File test2. The scope File test2 has test1(), and calls it.

enter image description here

Upvotes: 1

Views: 1797

Answers (1)

Ziyad Edher
Ziyad Edher

Reputation: 2150

Python module importing and global namespace management is a very broad topic, so I will limit this answer to the specific case that you are seeing.

In general, Python works very sequentially.

  1. You open the interpreter, certain special values such as environment variable and other kernel variables are injected into the global namespace.
  2. You execute import test2, this goes to the test2.py file in the local directory and executes that file in the same Python environment.
  3. While executing test2.py, Python comes across from test1 import test1.
  4. Similar to step 2, Python goes and finds test1.py, it does some extra things because you are importing a function in the module rather than the module itself, but in general, at this point, test1 (the function) gets placed in the current scope.
  5. You call test2.test2(), since test2 has been imported in step 2, it exists and so does test2.test2. So the interpreter jumps to test2.test2 and test1 is called and since it is in namespace (we just imported it in step 3) no error is thrown, then your second print statement is called.

Things are obviously a bit more complicated than this on the low-level, but this does give a general overview of how Python deals with this stuff.

Upvotes: 1

Related Questions