Python
Dynamic Import
Module Loading
Programming
Code Tutorial

How can I import a module dynamically given its name as string?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If you need to import a Python module whose name is only known at runtime, the standard solution is importlib.import_module(). That approach is clearer and safer than trying to build source strings and execute them, and it works naturally with normal Python import rules.

The standard API: importlib.import_module

python
1import importlib
2
3module_name = "json"
4mod = importlib.import_module(module_name)
5
6print(mod.dumps({"ok": True}))

This is the direct modern answer. It behaves like a normal import, except the module name is provided dynamically.

It also supports dotted module paths.

python
1import importlib
2
3module = importlib.import_module("xml.etree.ElementTree")
4print(module.Element("root"))

Why not use __import__ directly

Python still has the lower-level built-in __import__, but importlib.import_module() is easier to read and usually the better choice in application code.

So unless you are doing something very specialized, use importlib.

Loading a class or function by name

Often the real goal is not “import a module” but “load a specific object from a module.” In that case, import first and then resolve the attribute.

python
1import importlib
2
3
4def load_object(path: str):
5    module_name, attr_name = path.split(":", 1)
6    module = importlib.import_module(module_name)
7    return getattr(module, attr_name)
8
9sqrt = load_object("math:sqrt")
10print(sqrt(81))

This is common in plugin systems, task runners, and configuration-driven frameworks.

Handling errors cleanly

Dynamic imports fail for predictable reasons, so catch them intentionally.

python
1import importlib
2
3try:
4    mod = importlib.import_module("not_a_real_module")
5except ModuleNotFoundError as exc:
6    print("Import failed:", exc)

If you are loading an attribute as well, you may also need to catch AttributeError.

Importing from a file path

If the code is not installed as an importable package, you can still load it from a file using importlib.util.

This is useful for plugin folders, internal tooling, and experiments, but it is more advanced than ordinary imports and should be used deliberately rather than as a default loading mechanism.

python
1import importlib.util
2from pathlib import Path
3
4path = Path("plugins/example_plugin.py")
5spec = importlib.util.spec_from_file_location("example_plugin", path)
6module = importlib.util.module_from_spec(spec)
7spec.loader.exec_module(module)
8
9print(module)

This is useful for plugin directories or internal tooling, but it is a more advanced path than ordinary module import by name.

A common plugin pattern

python
1import importlib
2
3PLUGINS = ["json", "math", "statistics"]
4
5loaded = []
6for name in PLUGINS:
7    loaded.append(importlib.import_module(name))
8
9for module in loaded:
10    print(module.__name__)

This pattern keeps configuration data separate from hardcoded imports.

Security and design caution

Dynamic imports are powerful, but do not treat arbitrary untrusted strings as import targets without validation. If a user controls the module name completely, they may be able to load modules you never intended to expose.

In many systems the safer design is a registry of approved plugin names mapped to import targets, so configuration stays flexible without turning import resolution into a free-form execution surface.

A safer design is often to allow only a known set of approved module names or entry points.

Common Pitfalls

A common mistake is using exec() or dynamically constructed import statements instead of importlib.

Those approaches are harder to read, harder to validate, and usually less safe than using the import APIs Python already provides.

Another mistake is forgetting that a dynamic import can raise both module-level and attribute-level errors.

A third mistake is letting unvalidated external input drive import targets directly in a plugin or configuration system.

Summary

  • Use importlib.import_module() for ordinary dynamic imports by string name.
  • Use getattr() after import if you need a specific function or class.
  • Use importlib.util when importing from a file path rather than an installed module name.
  • Handle ModuleNotFoundError and AttributeError cleanly.
  • Validate dynamic import targets when the names come from external input.
  • Prefer a small approved registry over unrestricted import strings in production systems.

Course illustration
Course illustration

All Rights Reserved.