What a module is

A module is a file of Python code that other code can import. Any file ending in .py is a module; its name is the file name without the extension, so prices.py is the module prices. The functions, classes and variables defined at the top level of that file become the module's contents.

Modules solve two problems. They let you split a growing program into files that each do one job, and they let you reuse code: a function written once in a module can be imported by any number of programs. Python itself ships with hundreds of modules, the standard library, and the rest of this page uses them for examples.

For example, a small module for a shop could look like this:

# prices.py
VAT_RATE = 0.21


def with_vat(amount):
    """Return the amount including VAT, rounded to cents."""
    return round(amount * (1 + VAT_RATE), 2)

A second file in the same folder can then use it with import prices and call prices.with_vat(10.0).

Importing

The import statement loads a module and gives your code a name to reach it by. The first time a module is imported, Python runs its code from top to bottom and keeps the resulting module object in memory. Importing it again, from any file, reuses that object instead of running the code a second time. By convention, all imports go at the top of a file.

import module

The plain form binds the module itself to a name. You then reach its contents with a dot, which makes it obvious where each name comes from.

import math

print(math.sqrt(16))
print(math.pi)
print(math.floor(7.8))
4.0
3.141592653589793
7

import module as alias

as gives the module a different name in your file. This is useful for long names or for well-known community abbreviations such as import numpy as np.

import statistics as stats

temperatures = [18.5, 21.0, 19.5]
print(stats.mean(temperatures))
print(stats.median(temperatures))
19.666666666666668
19.5

from module import name

from … import … copies selected names from the module into your file, so you use them without the module prefix. The module name itself is not defined afterward.

from math import pi, sqrt

radius = 2
print(round(pi * radius ** 2, 2))
print(sqrt(81))
12.57
9.0

You can rename here too: from math import sqrt as root.

Why to avoid from module import *

from math import * imports every public name in the module at once. It saves typing, but it hides where names come from, and it can silently replace names you already have. After the import below, pow is no longer the built-in function but math.pow, which always returns a float:

print(pow(2, 3))

from math import *

print(pow(2, 3))
8
8.0

Import the names you need explicitly, or import the module and use the dot. Linters and the PEP 8 style guide both discourage wildcard imports.

How Python finds modules

When you write import prices, Python first checks whether the module is already loaded. If not, it searches the folders in the list sys.path, in order, and uses the first match. That list starts with:

  1. The folder that contains the script you ran (or the current folder, in the REPL).
  2. The folders in the PYTHONPATH environment variable, if it is set.
  3. The standard library.
  4. The site-packages folder where third-party packages are installed.

You can print the list to see it on your own machine:

import sys

for folder in sys.path:
    print(folder)

Some modules, such as sys (and, in many builds, math), are built into the interpreter itself and are found before this search even starts.

Shadowing a standard module

Because the script's own folder comes first, a file of yours with the same name as a standard module wins. Suppose you are learning about random numbers and save your experiment as random.py:

# random.py  (a bad file name)
import random

print(random.randint(1, 6))

Running python3 random.py fails. The line import random finds your file instead of the standard module, so random has no randint:

AttributeError: partially initialized module 'random' has no attribute 'randint' (most likely due to a circular import)

Python 3.13 and later add a hint to this message, suggesting you rename the file. The same problem can break other modules that import random behind the scenes, such as statistics.

Running versus importing: __name__

Python automatically sets a variable __name__ in every module. It holds the module's name. There is one exception: in the file you run directly, Python sets __name__ to the string "__main__".

import math

print(math.__name__)
print(__name__)
math
__main__

That makes it possible for a file to be both a reusable module and a runnable program. Put the code that should only run when the file is started directly under an if test:

def celsius_to_fahrenheit(celsius):
    return celsius * 9 / 5 + 32


def main():
    for celsius in (0, 20, 100):
        print(celsius, "°C =", celsius_to_fahrenheit(celsius), "°F")


if __name__ == "__main__":
    main()
0 °C = 32.0 °F
20 °C = 68.0 °F
100 °C = 212.0 °F

Run this file as python3 convert.py and it prints the table. Another file can import convert to use celsius_to_fahrenheit() without the table being printed, because in that case __name__ is "convert".

Packages

A package is a folder of modules that is imported as one unit. It lets you group related modules and give them a shared name, the same way folders group files. A package can contain subpackages, which are simply folders inside it.

shop/
├── main.py
└── billing/
    ├── __init__.py
    ├── invoices.py
    └── taxes.py

From main.py, the modules in billing are reached with dotted names:

# main.py
import billing.taxes
from billing import invoices
from billing.taxes import with_vat

print(billing.taxes.with_vat(10.0))
print(with_vat(25.0))

The __init__.py file

The file __init__.py marks a folder as a regular package. It runs once, when the package is first imported, and it is often empty. It can also import the most useful names from the package's modules, so users can write from billing import with_vat instead of reaching into billing.taxes.

The standard library and third-party packages

The modules you have used so far — math, statistics, sys — belong to the standard library: they are installed together with Python, so every Python installation has them.

Everything else is a third-party package, written by someone outside the core Python team. Well-known examples are requests (HTTP), pandas (data tables) and flask (web applications). These packages are published on PyPI, the Python Package Index at pypi.org: the official public repository of Python packages, with hundreds of thousands of projects. Before you can import one, you have to install it.

Installing packages with pip

pip is Python's standard package installer. It downloads packages from PyPI, together with the packages they depend on, and installs them where Python can import them. The common commands:

python3 -m pip install requests          # install the latest version
python3 -m pip install "requests==2.32.3"  # install an exact version
python3 -m pip install --upgrade requests  # upgrade to the latest version
python3 -m pip uninstall requests        # remove a package
python3 -m pip list                      # show installed packages
python3 -m pip show requests             # details of one package

On Windows, replace python3 with py (or python).

Why python3 -m pip

Many systems also have a plain pip command, but a computer often has more than one Python installed, and pip may belong to a different one than python3. python3 -m pip runs pip as a module of exactly the interpreter you name, so packages always land where that interpreter looks for them. Inside an activated virtual environment (below), pip and python -m pip are the same thing.

Freezing requirements

pip freeze prints every installed package with its exact version. Saved to a file named requirements.txt, that list lets anyone recreate the same set of packages:

python3 -m pip freeze > requirements.txt   # save the list
python3 -m pip install -r requirements.txt  # install everything in it

A requirements file is plain text, one package per line:

certifi==2024.8.30
charset-normalizer==3.4.0
idna==3.10
requests==2.32.3
urllib3==2.2.3

Commit requirements.txt to version control; it is how other people, and servers, install what your project needs.

Virtual environments

By default, pip installs packages for the whole Python installation. That causes trouble quickly: project A needs version 1 of a package, project B needs version 2, and only one can be installed. A virtual environment solves this. It is a folder with its own Python executable and its own site-packages, so each project gets a separate, isolated set of packages that cannot conflict with other projects or with the system.

Creating and activating one

The venv module in the standard library creates a virtual environment. Run it once, in the project folder. The name .venv is a common convention. On Debian and Ubuntu, install the venv module first: sudo apt install python3-venv.

python3 -m venv .venv

Then activate it in each new terminal session. Activation puts the environment's python and pip first on your path, and most shells show its name in the prompt.

# macOS and Linux
source .venv/bin/activate

# Windows (PowerShell)
.venv\Scripts\Activate.ps1

# Windows (Command Prompt)
.venv\Scripts\activate.bat

While it is active, python and pip refer to the environment, and everything you install stays inside .venv. When you are done, leave it with:

deactivate

A typical start of a new project therefore looks like this (macOS or Linux):

python3 -m venv .venv
source .venv/bin/activate
python -m pip install requests
python -m pip freeze > requirements.txt

The externally-managed-environment error

On many recent Linux distributions (such as Debian 12 and Ubuntu 23.04 and later), and with Homebrew's Python on macOS, pip install outside a virtual environment stops with an error:

error: externally-managed-environment

× This environment is externally managed

This is deliberate. The system's Python is managed by the operating system's package manager, and system tools depend on it; packages installed with pip could overwrite or break those. The fix is exactly what this page recommends anyway: create a virtual environment and install there. For Python packages the system provides, you can also use the operating system's package manager (for example apt install python3-requests).