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.

DefinitionsPython 3 (all)Live demo
import
import json
import os.path
import as
import numpy as np
from import
from math import sqrt, pi
from os import path as p
from import *
from itertools import *
relative
from . import utils
from ..models import User
Use for
import mod / import mod as m / from mod import name
Result
a statement; binds a name (module or attribute) in the current scope
Pairs with
as, sys.modules, __all__, if __name__ == "__main__"
Watch out
from mod import x copies the current value; star imports can shadow builtins

Demo

Live evaluation
Type a name. Is it in the module, and does a star import copy it? itertools has no __all__, so * takes every name that does not start with an underscore.
Try:
Inputs
namestra name
Code
import itertools

ns = {}
exec('from itertools import *', ns)
name = 'chain'
(name in dir(itertools), name in ns)
Result
(True, True)

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

NameTypeRequiredDescription
moduledotted nameyesModule or package to load, e.g. json, os.path. With leading dots (from . / from ..) it is relative to the current package.
nameidentifiernofrom form only: an attribute of the module (or a submodule) to bind. * binds every public name.
as aliasidentifiernoBind under this name instead. import a.b as x binds the submodule a.b itself as x.

Common patterns

Script entry point
Code under this guard runs when the file is executed, not when it is imported.
def main():
    ...

if __name__ == '__main__':
    main()
Optional dependency with a fallback
Catch ImportError (ModuleNotFoundError is a subclass) to fall back to the standard library.
try:
    import ujson as json
except ImportError:
    import json
Control what * exports
__all__ lists the public names; from module import * takes exactly these.
__all__ = ['load', 'save']

def load(path): ...
def save(path, data): ...
def _helper(): ...
Relative imports inside a package
One dot is the current package, two dots the parent. Only works in a module that is part of a package.
from . import utils
from .models import User
from ..config import settings

Examples

1. import binds the module name
import math math.sqrt(16)
Returns
4.0
2. as gives it a shorter name
import itertools as it list(it.islice('abcdef', 3))
Returns
['a', 'b', 'c']
3. from copies names out
from collections import Counter Counter('banana').most_common(1)
Returns
[('a', 3)]
4. The module object is cached
import json import sys json is sys.modules['json']
Returns
True
5. import a.b binds only a
import xml.dom (xml.__name__, xml.dom.__name__)
Returns
('xml', 'xml.dom')
6. A missing name in the module
from itertools import izip
Returns
ImportError: cannot import name 'izip' from 'itertools' (unknown location)
7. A missing module
import nosuchmodule
Returns
ModuleNotFoundError: No module named 'nosuchmodule'
8. Relative import outside a package
from . import helpers
Returns
ImportError: attempted relative import with no known parent package

Pitfalls

1. from module import name copies the value, not a live link
from config import debug binds your own name to the object debug referred to at that moment. Rebinding config.debug later does not change your copy. Import the module and read the attribute when you need it.
stale copy
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
False
read it through the module
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
True
2. A star import silently shadows a builtin
os exports its own open(), a low-level function that wants integer flags. After from os import *, the builtin open is gone from your module.
from os import *
from os import *
open('notes.txt', 'w')
TypeError: 'str' object cannot be interpreted as an integer
import the module
import os
with open('notes.txt', 'w') as f:
    f.write('hi')
os.path.getsize('notes.txt')
2
3. import a.b does not bind b
The plain form binds the top-level package name only; the submodule is reached through it. Use from a import b (or import a.b as b) to get a short name.
expects a name decoder
import json.decoder
decoder.JSONDecodeError
NameError: name 'decoder' is not defined
from json import decoder
from json import decoder
decoder.JSONDecodeError.__name__
'JSONDecodeError'

When to use

Use it
  • 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)
Reach for something else
  • 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

CPython impl
import checks sys.modules first; only on a miss does it search sys.meta_path finders, create the module, put it in sys.modules and then run its code
Scope
import is an assignment: inside a function it binds a local name, and the global/nonlocal declarations apply to it
Circular imports
If a imports b and b imports a, b sees a partially initialised module. from a import x then fails with an ImportError that says "partially initialized module" and "most likely due to a circular import". In 3.13, when the module sits in the script’s own directory, the same failure is reported with a "consider renaming" hint instead — it can look like a name clash with the standard library
from / as elsewhere
from also appears in yield from and raise ... from; as also appears in with ... as and except ... as — those are covered on their own pages
Built-in modules
Modules compiled into the interpreter (sys, itertools, builtins) have no file, so their ImportError says (unknown location) where a file module shows its path

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.