HOWTO · Python
How to Import All Modules in One Directory in Python
This tutorial discusses how to import all modules in a directory in Python.
On this page
To import modules from one directory, treat that directory as a Python package. For a fixed set of modules, list the imports in the package’s __init__.py; when the module names are not known in advance, discover and import them by their package-qualified names with importlib.
Import All Modules Present in One Directory in Python
A package can organize related modules and provide a convenient interface to them. For example, the package a can contain x.py, y.py, and z.py, alongside __init__.py. The initializer runs when Python imports the package. It does not automatically import sibling files: put explicit imports there when you want those modules available as package attributes.
The following self-contained example creates that package, imports its modules in the initializer, and accesses each module through a:
from pathlib import Path
import sys
from tempfile import TemporaryDirectory
with TemporaryDirectory() as temp_dir:
package_dir = Path(temp_dir) / "a"
package_dir.mkdir()
(package_dir / "x.py").write_text("value = 'X'\n", encoding="utf-8")
(package_dir / "y.py").write_text("value = 'Y'\n", encoding="utf-8")
(package_dir / "z.py").write_text("value = 'Z'\n", encoding="utf-8")
(package_dir / "__init__.py").write_text(
"from . import x, y, z\n", encoding="utf-8"
)
sys.path.insert(0, temp_dir)
try:
import a
assert (a.x.value, a.y.value, a.z.value) == ("X", "Y", "Z")
finally:
sys.path.remove(temp_dir)
for module_name in list(sys.modules):
if module_name == "a" or module_name.startswith("a."):
sys.modules.pop(module_name, None)
In the supplied candidate-bound execution, both examples completed successfully with exit code 0 and no standard output.
The relative imports in __init__.py make the modules available as a.x, a.y, and a.z after import a. This explicit list is easy to review and gives the package a predictable interface. Keep the initializer focused: importing a package executes its initializer and the imported modules’ top-level code, so avoid putting unrelated work or costly side effects there.
Use importlib for Advanced Module Importing
If another part of a program adds modules over time, a fixed import list may not fit. Package-aware discovery can find immediate modules and load them by qualified name. This standalone example creates a package, discovers its modules with pkgutil, and stores each imported module in a dictionary:
from pathlib import Path
import importlib
import pkgutil
import sys
from tempfile import TemporaryDirectory
with TemporaryDirectory() as temp_dir:
package_dir = Path(temp_dir) / "plugins"
package_dir.mkdir()
(package_dir / "__init__.py").write_text("", encoding="utf-8")
(package_dir / "alpha.py").write_text("value = 1\n", encoding="utf-8")
(package_dir / "beta.py").write_text("value = 2\n", encoding="utf-8")
sys.path.insert(0, temp_dir)
try:
package = importlib.import_module("plugins")
modules = {
item.name: importlib.import_module(f"{package.__name__}.{item.name}")
for item in pkgutil.iter_modules(package.__path__)
if not item.ispkg
}
assert sorted(modules) == ["alpha", "beta"]
assert modules["alpha"].value == 1
assert modules["beta"].value == 2
finally:
sys.path.remove(temp_dir)
for module_name in list(sys.modules):
if module_name == "plugins" or module_name.startswith("plugins."):
sys.modules.pop(module_name, None)
This example writes no standard output:
Use modules["alpha"] to access an imported module object, then read its attributes or call its functions. The discovery above covers immediate modules in the package and skips subpackages; change that policy deliberately if nested packages should also load. It does not filter by an application-specific naming convention, so add a predicate if only selected modules are plugins. Every discovered module is executed during import and can require dependencies or perform its own initialization. A missing dependency or an error in module code can stop the loading loop. Dynamic loading is useful when the set is genuinely extensible, but for a known set of modules, explicit imports are clearer and easier to maintain. Because importing happens in the current process, limit discovery to trusted package contents. For packages with costly initialization, keep plugin registration separate from module loading and document which names callers can rely on.
Conclusion
Use explicit imports in __init__.py when the package’s public modules are known. Use package-aware discovery with importlib when the program must load an evolving set of modules, and make the discovery rules and import side effects clear to callers.