Course Content
Python Essentials for AI Engineer
6 sections · 48 lessons
What are the different import styles?
What you need to know
What each style puts in your namespace
1import math # binds: math2import json as js # binds: js3from math import sqrt, pi # binds: sqrt, pi4from statistics import mean # binds: mean56print(math.floor(2.7), js.dumps([1]), sqrt(16), round(pi, 2), mean([1, 2, 3]))7# 2 [1] 4.0 3.14 2| Style | Pros | Cons |
|---|---|---|
import module | clear origin at every use | longer names |
import module as m | short, conventional for np, pd, plt | confusing if the alias is unusual |
from module import name | short, explicit list | name origin less obvious far from the import |
from module import * | quick in a REPL | hidden names, shadowing, linters can't help |
from . import sibling | stays valid if the package is renamed | only works inside a package |
How import * bites
1print(pow(2, 10, 1000)) # 24 -> built-in pow supports a modulus2from math import * # silently replaces pow with math.pow3try:4 pow(2, 10, 1000)5except TypeError as e:6 print(e) # pow expected 2 arguments, got 3Nothing warned you. In a notebook with twenty cells, the failing line may be far from the import.
Relative imports
from .chunking import split_text means "from the module chunking in my own package". It only works when the file is imported as part of a package. Running python rag/loaders.py directly gives ImportError: attempted relative import with no known parent package; run python -m rag.loaders from the project root instead.
Ordering and placement
PEP 8 puts imports at the top of the file, in three groups: standard library, third-party, then your own modules. Tools like Ruff and isort sort them automatically.
A real-life example
A team's command-line tool, bot-admin, took 6 seconds to print --help, because its top-level imports pulled in torch and a tokenizer library that only the train subcommand needed. Moving those imports inside the function that uses them made --help instant:
1def cmd_train(args):2 import json # stands in for a heavy import like torch3 return json.dumps({"training": args})45def cmd_help():6 return "usage: bot-admin [train|help]"78print(cmd_help()) # usage: bot-admin [train|help]A function-level import runs only when the function is called (and only once, thanks to sys.modules). The same trick breaks a circular import — module A importing B while B imports A — though restructuring shared code into a third module is the cleaner fix.
Follow-up questions to expect
- "Why avoid
from x import *?" — It hides where names come from, can silently overwrite your names or built-ins, and prevents linters from catching undefined names. - "Absolute or relative imports?" — Absolute (
from support_bot.rag import chunking) is clearer and recommended by PEP 8; relative is fine within a package for short sibling references. - "What is a circular import and how do you fix it?" — Two modules importing each other at the top level, so one sees the other half-initialised. Move shared code to a third module, or import inside the function.