A module is a file
import greet binds one name, greet, to a module object; the functions live on it. from greet import hello binds the function directly — shorter at the call site, and it loses the context that says where hello came from. For anything but a very familiar name, the qualified form reads better.
# greet.py
GREETING = "hi"
def hello(name):
return f"{GREETING}, {name}"
import greet # greet.hello("ada")
import greet as g # g.hello("ada")
from greet import hello # hello("ada")
from greet import hello as hi # hi("ada")
from greet import * # don't. It hides where names came from.
What import does, once
This is why editing a file has no effect on a program already running, and why a module’s top level should only define things. Anything expensive or side-effecting at module level happens exactly once, at an unpredictable moment, in an order decided by whoever imported first.
import sys
"greet" in sys.modules # True after the first import
import importlib
importlib.reload(greet) # run the file again — for a REPL, not for production
del sys.modules["greet"] # the blunt version
Where it looks
Name a file after a standard-library module — random.py, json.py, email.py — and your file wins, because the script directory comes first. The resulting error is always confusing and never mentions the real cause.
import sys
sys.path # a list, searched in order:
# the directory of the script being run (or the cwd)
# anything in PYTHONPATH
# the standard library
# site-packages
__name__, and the guard
__name__ is "__main__" when the file is the one being run, and the module’s own name when it is imported. The guard means "only do this if I am the program, not a library" — without it, importing your script runs it.
def main():
...
if __name__ == "__main__":
main()
Packages
A package is a directory Python treats as a module. Since 3.3 __init__.py is not strictly required, but including it keeps the boundary explicit and lets the package choose what it exports.
shop/
__init__.py # marks the package; often empty, sometimes the public surface
cart.py
pricing/
__init__.py
tax.py
from shop.pricing import tax # absolute — always prefer this
from .pricing import tax # relative, only inside the package itself
from shop import cart # __init__.py decides what shop exposes