The Import System Interview Questions & Answers
5 questions Updated 2026-06-18
Python interview questions on the import system — modules vs packages, absolute vs relative imports, __main__, sys.path module resolution, import caching, and circular imports.
A module is a single .py file — a namespace of functions, classes, and
variables you can import. A package is a directory of modules; it
groups related modules under one dotted namespace (mypkg.utils).
Historically a package needed an __init__.py file to be recognized; that file
runs when the package is first imported and can expose a curated public API.
Since Python 3.3, a directory without __init__.py can still be a namespace
package, but a regular package with __init__.py is the common, explicit choice.
# file layout
# mypkg/
# __init__.py <- makes it a regular package
# utils.py <- a module inside the package
import mypkg.utils # import a module from a package
from mypkg import utils # same module, bound as `utils`
Why it matters: modules are the unit of code reuse, packages are the unit of
organization — both are objects at runtime (module.__file__, package.__path__).
An absolute import spells out the full path from a top-level package
(from mypkg.utils import helper). A relative import uses leading dots to
navigate relative to the current module's package — one dot for the current
package, two for the parent.
# inside mypkg/sub/thing.py
from mypkg.utils import helper # absolute — explicit, unambiguous
from ..utils import helper # relative — '..' = mypkg, then .utils
from . import sibling # relative — same package
Relative imports only work inside a package and only when the module is run as
part of that package — running the file directly with python thing.py breaks them
(ImportError: attempted relative import with no known parent package).
Rule of thumb: PEP 8 prefers absolute imports for clarity; reach for relative imports inside large packages to avoid repeating a long package prefix.
Every module has a __name__ variable. When a file is run directly, Python
sets its __name__ to the string "__main__". When the same file is imported,
__name__ is set to the module's name instead. The guard therefore runs code
only when the file is executed as a script, not when it's imported.
def main():
print("running as a program")
if __name__ == "__main__": # True only via `python myfile.py`
main() # skipped when `import myfile`
This lets a file double as both an importable library and a runnable program: tests and other modules can import its functions without triggering the script logic.
Rule of thumb: put executable entry-point code under the guard so importing the module stays free of side effects.
On import x, Python searches a list of finders and, for file-based modules,
walks sys.path — a list of directories — in order, using the first match.
sys.path is built from the script's directory (or cwd), the PYTHONPATH
environment variable, and the installation's standard library / site-packages.
import sys
print(sys.path) # ['', '/usr/lib/python3.12', '.../site-packages', ...]
# '' (or the script dir) is searched first — local files can SHADOW stdlib!
# a file named random.py in your folder will hide the real `random` module
Built-in modules and frozen modules are found before sys.path is consulted, which
is why you can't shadow sys itself.
Why it matters: a local file named like a stdlib module (queue.py, email.py)
silently shadows the real one — a classic, confusing import bug.
sys.modules is a cache mapping module names to already-imported module
objects. The first import of a module executes its code top to bottom and stores
the result there; every later import of the same name just returns the cached
object — so module code runs once per interpreter session.
A circular import is when module A imports B while B imports A. Because the
importing module is added to sys.modules before its body finishes running, the
second import gets a partially-initialized module — names defined later in the
file aren't there yet.
# a.py
import b # starts importing b...
def helper(): ...
# b.py
import a # a is in sys.modules but only HALF-defined
print(a.helper) # AttributeError — helper isn't bound yet
Fixes: move the import inside the function that needs it (deferred until call time), restructure to remove the cycle, or import the module object rather than names from it. Rule of thumb: circular imports usually signal that two modules should share a third.
Practice tests are coming soon
Get notified when interactive mock interviews and quizzes launch.