import
import finds a module, runs it the first time only, stores it in sys.modules and binds a name. from ... import copies names out of it; as renames.
import json import os.path
import numpy as np
from math import sqrt, pi from os import path as p
from itertools import *
from . import utils from ..models import User
Demo
import itertools ns = {} exec('from itertools import *', ns) name = 'chain' (name in dir(itertools), name in ns)
In the star tab, _tee and __name__ exist in itertools but are not copied: without __all__, * skips every name starting with an underscore (and exec adds __builtins__ to the namespace itself, which is why that one shows up). A module that defines __all__ exports exactly that list instead. In the cache tab, the count equals the number of imports because each import statement returns the object already in sys.modules. With 0 the import never executed, so the name it was never bound: import is an assignment that happens when the line runs.
Syntax slots
| Name | Type | Required | Description |
|---|---|---|---|
| module | dotted name | yes | Module or package to load, e.g. json, os.path. With leading dots (from . / from ..) it is relative to the current package. |
| name | identifier | no | from form only: an attribute of the module (or a submodule) to bind. * binds every public name. |
| as alias | identifier | no | Bind under this name instead. import a.b as x binds the submodule a.b itself as x. |
Common patterns
def main(): ... if __name__ == '__main__': main()
try: import ujson as json except ImportError: import json
__all__ = ['load', 'save'] def load(path): ... def save(path, data): ... def _helper(): ...
from . import utils from .models import User from ..config import settings
Examples
Pitfalls
import sys, types config = types.ModuleType('config') config.debug = False sys.modules['config'] = config try: from config import debug config.debug = True result = debug finally: del sys.modules['config'] result
import sys, types config = types.ModuleType('config') config.debug = False sys.modules['config'] = config try: import config config.debug = True result = config.debug finally: del sys.modules['config'] result
from os import * open('notes.txt', 'w')
import os with open('notes.txt', 'w') as f: f.write('hi') os.path.getsize('notes.txt')
import json.decoder decoder.JSONDecodeError
from json import decoder decoder.JSONDecodeError.__name__
When to use
- import module — the default; call sites read module.name and stay clear
- import long.module.name as short — conventional aliases (np, pd) or long dotted paths
- from module import name — a few names you use often (from pathlib import Path)
- from module import * in real code → explicit names (star imports are fine in the REPL)
- Importing to re-run a module’s code → call a function it defines (importlib.reload only in development)
- Modifying sys.path to reach your own code → install the project or run it as a package (python -m pkg.mod)
Notes
FAQ
import x binds the module; you write x.y each time and always see the module’s current value. from x import y binds y directly in your namespace — shorter to use, but it is a copy of the reference taken at import time. Both load and run the module the same way.