🎓 A1Learner
🔍

Python How Imports Work

An import loads a module so a program can use its names. Python checks the sys.modules cache first.

The cache is checked first

sys.modules is a dict of loaded modules. Right after import math, the name is already in the dict.

import math
import sys

print("math" in sys.modules)

The search list

Python searches these folders in order. The list differs on each computer, so no output is shown here.

import sys

for place in sys.path:
    print(place)

A circle, and a way out

Each module waits for the other to finish. Moving the shared code into a third module breaks the circle.

# a.py
import b

# b.py
import a   # a is not finished loading yet

__all__ picks the star names

The secret function exists in stars.py. It stays out, because __all__ does not list it.

# stars.py
__all__ = ["greet"]


def greet():
    return "hi"


def secret():
    return "shh"

# use_stars.py
from stars import *

print(greet())
print("secret" in globals())

Example

# File: main.py
import os

import facts.alpha

print("main name:", __name__)
print("main file:", os.path.basename(__file__))

# File: facts/__init__.py
# (this file is empty)

# File: facts/alpha.py
import os

print("alpha name:", __name__)
print("alpha file:", os.path.basename(__file__))

Key points

  • Import: loading a module so your program can use its names
  • Cache: Python checks sys.modules first.
  • That dict holds every module already loaded
  • Use a finder to search for a module.
  • Use a loader to run its code and build the module
  • sys.path order: the script folder first, then PYTHONPATH folders, then the standard library, then site-packages
  • site-packages: the folder where installed packages live
  • Namespace: the set of names that belongs to one module.
  • Each module keeps its own set
  • __file__: a variable that holds the path of the module's own file
  • Circular import: two modules import each other, and neither one can finish loading
  • Fix a circle by moving shared code into a third module.
  • Or import inside a function, after both modules exist
  • __all__: a list in a module that names what import * may take from it

In this example, the scratch folder holds main.py and a package folder named facts. The facts folder holds an empty __init__.py file and alpha.py. The command is python3 main.py, run inside that scratch folder. The import line runs alpha.py first, so the alpha lines print before the main lines. Inside alpha, __name__ is facts.alpha, its full module name. Inside main, __name__ is __main__, because main.py was run directly. os.path.basename keeps only the file name part of a path. So no computer-specific folder path is ever printed.

Note

The top-level code of a module runs only on its first import.

Later imports reuse the cached module.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Python Playground

Exercise

Python needs to import a module. What does it check first?