Modules & Packages
An import in Python is not textual substitution and not "including a header" the way C does it. import mymod means four separate actions: locate the file along the sys.path list, execute it top to bottom exactly once, collect the resulting names into a module object, and bind that object to a name in the current namespace. A module is therefore a first-class object, not a line in a build system: you can pass it to a function, put it in a list, read it with getattr. A package is the same module object, with one extra attribute — __path__, the list of directories searched for submodules.
Almost every practical problem in this topic grows out of those two points — "executed exactly once" and "found along sys.path". A repeated import does not re-read the file; it pulls the ready object out of the sys.modules dictionary, so top-level code runs once per process and module globals behave like a program-wide singleton. The search walks the directories in order and stops at the first match, so your own queue.py next to the script silently replaces the standard one for the whole process. And from module import name copies a reference to the object, not a link to the module — later assignments to module.name never reach your copy. Work through each mechanism in the layers below.
Topic map
- The module and its execution — what
importcreates, why the file runs only once, and how a module namespace is built. - How import works —
sys.modules,sys.pathorder, the first-match rule, finder and loader, circular imports. - Packages and namespace packages —
__init__.py, the__path__attribute, relative imports, and PEP 420 packages without__init__.py. - The entry point and
__name__— where"__main__"comes from, why the guard exists, and howpython -mdiffers from running a file.
Common mistakes and traps
| Mistake | Consequence |
|---|---|
Thinking every import re-executes the file | The file runs once per process; later imports only fetch the object from sys.modules and bind a name |
| Thinking Python scans the whole filesystem for a module | The search runs strictly along the sys.path list and ends at the first matching directory |
| Naming your file after a standard-library module | The script directory comes first on sys.path, so your random.py shadows the standard one for the entire program, third-party libraries included |
Treating sys.path as an immutable tuple | It is an ordinary mutable list that gets edited at runtime — which is exactly why its ordering becomes a source of elusive bugs |
Expecting from config import DEBUG to see a later config.DEBUG = True | A value was copied, not a link to the module; the local name DEBUG still holds the old object |
Assuming import package pulls in the submodules | Only __init__.py runs; package.sub exists only if something imported it explicitly |
Demanding an __init__.py from every package | Under PEP 420 a directory without __init__.py imports as a namespace package and may be assembled from several paths at once |
Running a package file as python pkg/mod.py | __package__ is unset, relative imports fail, and a later import pkg.mod executes the file a second time under a different name |
What interviews check
The topic counts as basic and is asked mostly at junior and middle level, yet it is answered badly disproportionately often. The standard set is "what is a module", "what makes a directory a package", "what is __name__". An answer at the level of "a module is a .py file" is accepted, but the follow-up lands immediately: what happens on the second import of that same module. The right answer names sys.modules and single execution; the wrong one — "the file is read again" — turns the rest of the conversation into a review of why module globals behave like singletons and why importlib.reload exists at all. The second mandatory question is __name__, and the interviewer wants the reason for separating import from execution, not the memorised formula.
At middle level a question about module lookup is added. The expected answer is sys.path, the scan order and the first-match rule — and almost always the follow-up asks you to predict what happens when a file named after a standard-library module sits next to the script. The senior variant of the topic is PEP 420 namespace packages: how a package without __init__.py differs from a regular one, and why you would spread a single logical package across several separately installed distributions. There is one typical mistake here — claiming __init__.py is always mandatory; the second most common is calling a regular package with an empty __init__.py a namespace package, when the difference is fundamental, because only a namespace package is assembled from several sys.path directories.