Definition
A plain import brings in a whole module under its own name, which then has to be repeated in front of every borrowed item. Over two lines, nobody minds. When the same function shows up forty times, the prefix turns into noise.
from answers that precise annoyance: it states where the import comes from, then leaves the choice of what to take out of it. The requested item lands in the file and is used afterwards with no prefix.
from datetime import date
# date is now a name of this file, as if defined here
today = date.today()Without from, the same thing takes import datetime and then datetime.date.today(). On one line the difference is trivial; across a whole file, the module name vanishes from everywhere except the import line.
What is gained and what is lost
Why not use the shorter writing everywhere? Because it is paid for on the four points below.
import module | from module import x | |
|---|---|---|
| Writing | Longer, prefixed | Shorter, direct |
| Origin visible | Yes, at every use | No, only at the top of the file |
| Collision risk | Low | Real between two modules |
| Good ground | A module used everywhere | One or two specific items |
The origin row is the decisive one. With import module, every call recalls where the function comes from; with from, that information sits in one line at the top of the file, which is enough while the file stays short.
Name collision is the other side of the deal. As long as each is reached through its prefix, two modules exposing a function under the same name never get in the way; imported with from, they fight over the same slot.
When two from imports bring in the same name, the second overwrites the first without a word: no error, no warning. The program carries on, calls the wrong function, and the trouble only shows up later, far from its cause.
The form to avoid
from module import * pulls in everything the module exposes at once. The writing is tempting when trying something out quickly, and wrong in nearly every case.
The first damage hits readability: nothing shows where a name comes from any more, and a reader meeting join(...) can no longer tell whether it belongs to os.path, to a third-party library, or to the file itself. The tools follow, since a type checker no longer resolves those names.
The second damage is sneakier: the day the module adds a name, that name walks into your file and may cover one of your variables, while nothing has changed on your side.
# Banned: what enters the file is anyone's guess
from os.path import *
# Explicit, therefore readable and checkable by tools
from os.path import join, existsA module can restrict what this form exposes by declaring __all__, the list of names it agrees to hand out. The precaution softens the problem without removing it.
What actually happens in memory
A widespread hunch says that from datetime import date loads "just date", and therefore costs less than a full import. That is not what happens.
Python runs the module in full, just as for an ordinary import, then copies a single one of the resulting names into the calling file. The chosen form therefore changes nothing about startup or memory: it changes what stays visible afterwards.
That copy explains a puzzling behaviour. If the module later reassigns one of its variables, the name imported with from keeps the original value, when module.variable would see the new one. Enough to make hot reloading painful to reason about.
One import often puzzles readers: from __future__ import annotations. It carries no function, it switches on a behaviour planned for a later version of the language, and it must precede every other statement in the file.
Relative imports
Inside a package, from accepts a relative path written with dots: from .utils import clean points at a neighbouring module, from ..core import base goes up one level.
The benefit is not carving the package name into each of its files: rename it, and the internal imports keep working.
The catch lies in the launch. That path is worked out from the package the file belongs to, information Python only holds if the file was reached as a member of that package. Running a file buried deep in the tree directly then produces a puzzling ImportError: "attempted relative import with no known parent package".
The fix is to launch from the project root with python -m package.module. The same symptom paired with a ModuleNotFoundError points instead at a path problem.
Frequently asked questions
Does from always start a line?
Yes, it opens the statement, and PEP 8 asks for these lines to be grouped at the top of the file. The word from also appears in raise ValueError(...) from error, which chains two exception objects to keep the original cause: a use unrelated to imports.
Can several items be imported at once?
Yes, separated by commas: from math import sqrt, pi, floor. If the line grows too long, brackets around the list allow spreading it over several lines, which formatters do on their own. That beats one line per imported name.
How can a name conflict be avoided?
With as, which renames the item on import: two load functions become load_json and load_csv, and nothing gets overwritten. When doubt lingers, importing the whole module and keeping the prefix stays the better answer.