Part of Python for Beginners

Modules & Imports (import, from, as, custom modules, name) - Python Tutorial #17

Sandy LaneSandy Lane

Video: Modules & Imports (import, from, as, custom modules, name) - Python Tutorial #17 by Taught by Celeste AI - AI Coding Coach

Take the quiz on the full lesson page
Test what you've read · interactive walkthrough

Python Modules and Imports: import, from, as, name

import math — load a module. from math import sqrt — bring one name into your namespace. import datetime as dt — alias. if __name__ == "__main__": — run only when executed directly. Modules are how Python projects scale beyond a single file.

A module is a Python file. A package is a directory of modules. Imports are how one file uses code from another.

Importing a module

import math

print(math.sqrt(144))     # 12.0
print(math.pi)            # 3.141592653589793
print(math.ceil(3.2))     # 4
print(math.floor(3.8))    # 3

import math makes the math module available as math. Access its contents with dotted notation: math.sqrt, math.pi.

The first time import math runs, Python: 1. Finds math (built-in, then site-packages, then current directory). 2. Executes the module's top-level code. 3. Binds the module object to the name math.

Subsequent imports just retrieve the cached module — no re-execution.

from ... import

from random import randint, choice

print(randint(1, 10))                   # no need to write random.randint
print(choice(["apple", "banana"]))

from module import name brings name directly into your namespace. Use when you only need a few specific functions.

Comma-separate multiple imports:

from math import sqrt, pi, ceil, floor

You can do from module import * — but don't. It pollutes your namespace and hides where names came from.

import as

import datetime as dt

now = dt.datetime.now()
print(now.strftime("%Y-%m-%d"))

import X as Y aliases the module. Useful when:

  • The module name is long: import numpy as np, import pandas as pd.
  • The name conflicts with a local variable.
  • A widely-known convention: np, pd, plt for matplotlib.

You can alias inside from ... import too:

from helpers import calculate_area as area

Standard library tour

import math       # numerical functions
import random     # randomness
import datetime   # dates and times
import os         # OS interactions, paths
import sys        # interpreter, argv
import json       # JSON parsing
import re         # regex
import csv        # CSV files
import collections  # Counter, defaultdict, deque
import itertools   # combinatorial iterators
import functools   # caching, reduce, partial
import pathlib    # modern path handling

These ship with Python — no install needed. The standard library is huge; lessons later in this series cover each in depth.

Writing your own module

Any .py file is a module. Save this as helpers.py:

# helpers.py

def greet(name):
  return f"Hello, {name}!"

def calculate_area(length, width):
  return length * width

PI = 3.14159

Then in another file in the same directory:

# main.py
import helpers

print(helpers.greet("Alice"))
print(helpers.calculate_area(10, 5))

Or:

from helpers import greet, calculate_area

print(greet("Alice"))
print(calculate_area(10, 5))

The module name is the filename without .py.

name == "main"

# helpers.py
def greet(name):
  return f"Hello, {name}!"

if __name__ == "__main__":
  print("Testing helpers module:")
  print(greet("World"))

When Python runs a file directly, __name__ is "__main__". When the file is imported, __name__ is the module name ("helpers").

The if __name__ == "__main__": guard runs the test/demo code only when the file is run directly, not when imported. Standard pattern for "library + script" files.

Three import styles compared

# Style 1: import module
import helpers
helpers.greet("Alice")
helpers.calculate_area(10, 5)

# Style 2: from module import
from helpers import greet, calculate_area
greet("Alice")
calculate_area(10, 5)

# Style 3: import as
from helpers import calculate_area as area
area(10, 5)

When to use which:

  • Style 1 — many functions used; preserves module prefix for clarity.
  • Style 2 — a few specific functions used heavily; less typing.
  • Style 3 — long names or conflicts.

Packages: directories of modules

A package is a directory with an __init__.py file (which can be empty):

myproject/
  __init__.py
  utils.py
  database.py
  models/
    __init__.py
    user.py
    post.py
import myproject.utils
from myproject.database import connect
from myproject.models.user import User

Dotted paths mirror directory structure. The __init__.py runs when the package is first imported — useful for re-exporting, version, etc.

For modern projects (Python 3.3+), namespace packages can omit __init__.py, but most projects still include them for clarity.

sys.path: where Python searches

import sys
print(sys.path)
# ['', '/path/to/your/script', ..., 'site-packages']

Python looks for modules in:

  1. The directory of the running script.
  2. PYTHONPATH environment variable directories.
  3. Standard library locations.
  4. site-packages (where pip installs).

For projects, install your code as a package (pip install -e .) rather than fiddling with sys.path.

Relative vs absolute imports

# absolute (preferred):
from myproject.models.user import User

# relative (inside the same package):
from .models.user import User      # one level up
from ..utils import helper          # two levels up

Use absolute imports unless the relative form is shorter and clearly within the same package. Relative imports break if you move files; absolute imports remain stable.

Reload during development

If you're in a REPL and you've changed a module:

from importlib import reload
import helpers
reload(helpers)

In Jupyter, use the %autoreload magic. For scripts, just re-run.

dir() and help()

import math
print(dir(math))    # all names in the module
print(help(math.sqrt))   # docstring

dir(module) lists everything exported. Useful for exploring a new library.

Common stumbles

Circular imports. A imports B, B imports A. Python loads each file once, so the second import gets a partial module. Refactor: extract the shared code into a third module.

Same-name shadow. Naming your file random.py shadows the standard library random. Don't name files after stdlib modules.

Star imports. from module import * — pollutes namespace, hides where names come from, breaks linters. Avoid.

Forgetting if __name__ == "__main__":. Without it, import causes the demo code to run.

Modifying sys.path. Tempting, brittle. Install your package properly instead.

Cached old version. Edited a module, rerunning script shows old behavior. Restart your REPL or call importlib.reload.

What's next

Lesson 18: JSON. Reading and writing JSON files; json.loads, json.dumps, encoding nested structures.

Recap

import module for full module; from module import name for specific names; import as for aliases. Any .py file is a module; any directory with __init__.py is a package. if __name__ == "__main__": to make a file work as both library and script. Avoid from X import *. Use absolute imports for stability. Watch out for circular imports and stdlib-shadowing filenames.

Next lesson: JSON.

Ready? Take the quiz on the full lesson page →
Test what you've learned. Watch the lesson and try the interactive quiz on the same page.