What is a module in Python? Definition and examples

Learn what a module is in Python, how to import, create and use one effectively. Practical examples, best practices and comprehensive FAQ.
11 min read
Believemy logo

What is a module in Python?

In Python, a module is a file containing Python code — functions, classes, variables and executable statements — that you can reuse in other programs. A module has a .py extension and is one of the fundamental building blocks of code organization in Python. If you want to master modules and many other essential concepts, our comprehensive Python course will guide you step by step.

The module system allows you to break a large program into smaller files that are more readable and easier to maintain. Instead of writing everything in a single file, you group related functionalities into separate modules, then import them wherever you need them. This is the very essence of modularity in programming.

Good to know

A Python module is simply a .py file. If you have already written a Python script, you have already created a module without knowing it!

 

Detailed definition of a module

A module is a logical unit of code that encapsulates definitions and statements. Python distinguishes three main categories of modules:

Module typeDescriptionExample
Built-in moduleShipped with the Python installationmath, os, sys, json
Third-party moduleInstalled via pip from PyPIrequests, numpy, flask
Custom moduleCreated by the developermy_module.py

When you import a module, Python executes all the code contained in that file once, then caches the result. Subsequent imports of the same module reuse this cache, which is both efficient and performant.

A module can contain:

  • Functions defined with the def keyword
  • Classes defined with the class keyword
  • Variables and constants
  • Executable code (which runs upon import)
  • docstring to document the module

 

Importing a module in Python

Python offers several syntaxes for importing a module. Each has its advantages and use cases. Let's look at them in detail.

The import statement

The simplest way to import a module is to use the import keyword followed by the module name:

PYTHON
import math

# Usage with the module prefix
result = math.sqrt(144)
print(result)  # 12.0

pi = math.pi
print(pi)  # 3.141592653589793

With this syntax, you must always prefix the module's elements with its name (here math.). This is the most explicit method and the one that avoids name conflicts.

 

The from ... import statement

If you only need certain elements from a module, you can import them directly:

PYTHON
from math import sqrt, pi

# Direct usage, without prefix
result = sqrt(144)
print(result)  # 12.0
print(pi)  # 3.141592653589793

This syntax is more concise, but can lead to conflicts if two modules export identical names.

 

Importing with an alias

You can rename a module during import using the as keyword:

PYTHON
import numpy as np
import pandas as pd

array = np.array([1, 2, 3, 4, 5])
print(array.mean())  # 3.0

Aliases like np for NumPy or pd for Pandas are widely adopted conventions in the Python community.

 

Importing all elements with *

PYTHON
from math import *

# All elements from math are directly accessible
print(sqrt(25))  # 5.0
print(cos(0))    # 1.0
Warning

Importing with * is strongly discouraged in production. It pollutes the namespace, makes the code hard to read and can cause unpredictable name conflicts. Always prefer explicit imports.

Note that the __all__ variable allows you to control which elements are exported when a user uses from module import *.

 

Creating your own module

Creating a module in Python is extremely simple: just create a .py file and write code in it. Let's see a concrete example.

Step 1: Create the module file

Create a file named calculator.py:

PYTHON
"""Calculator module - Basic mathematical operations."""

PI = 3.14159265358979

def add(a, b):
    """Return the sum of a and b."""
    return a + b

def subtract(a, b):
    """Return the difference between a and b."""
    return a - b

def multiply(a, b):
    """Return the product of a and b."""
    return a * b

def divide(a, b):
    """Return the quotient of a divided by b."""
    if b == 0:
        raise ValueError("Division by zero is not allowed")
    return a / b

 

Step 2: Use the module

In another Python file located in the same directory, you can now import and use your module:

PYTHON
import calculator

result = calculator.add(10, 5)
print(result)  # 15

quotient = calculator.divide(20, 4)
print(quotient)  # 5.0

print(calculator.PI)  # 3.14159265358979

You can also use from ... import:

PYTHON
from calculator import add, divide

print(add(7, 3))    # 10
print(divide(15, 3))  # 5.0

 

The __name__ variable and the main pattern

The special variable __name__ plays an essential role in modules. When Python executes a file directly, it assigns the value "__main__" to __name__. When the file is imported as a module, __name__ takes the value of the module's name.

This mechanism allows you to create code that only runs when the file is executed directly:

PYTHON
# calculator.py

def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

if __name__ == "__main__":
    # This block only runs if the file is executed directly
    print("Calculator tests:")
    print(add(2, 3))       # 5
    print(subtract(10, 4)) # 6
    print("All tests pass!")
Good to know

The if __name__ == "__main__" pattern is an essential convention in Python. It allows you to make a module both importable and independently executable.

 

Packages: modules in folders

As your project grows, you will need to organize your modules into folders. In Python, a folder containing an __init__ file is called a package.

Here is a typical package structure:

PYTHON
my_project/
│
├── main.py
└── utils/
    ├── __init__.py
    ├── text.py
    ├── math_utils.py
    └── files.py

The __init__.py file can be empty or contain package initialization code. It tells Python that the folder should be treated as a package:

PYTHON
# utils/__init__.py
from .text import clean_text
from .math_utils import calculate_average

__all__ = ["clean_text", "calculate_average"]

You can then import from the package:

PYTHON
# main.py
from utils import clean_text, calculate_average
from utils.files import read_file

clean = clean_text("  Hello world  ")
average = calculate_average([10, 20, 30])

 

The most useful built-in modules

Python ships with an extremely rich standard library. Here are the most commonly used built-in modules:

ModulePurposeUsage example
osInteraction with the operating systemos.path.exists("file.txt")
sysSystem parameters and functionssys.argv, sys.exit()
jsonReading/writing JSON datajson.loads(), json.dumps()
datetimeDate and time manipulationdatetime.now()
randomRandom number generationrandom.randint(1, 100)
reRegular expressionsre.match(), re.findall()
collectionsAdvanced data structuresOrderedDict, namedtuple
pathlibFile path manipulationPath("folder/file.txt")

Let's see a concrete example using several built-in modules:

PYTHON
import os
import json
import datetime

# Check if a file exists
if os.path.exists("config.json"):
    # Read and parse the JSON file
    with open("config.json", "r") as f:
        config = json.load(f)
    print(f"Configuration loaded: {config}")
else:
    # Create a default configuration
    config = {
        "app_name": "MyApp",
        "version": "1.0",
        "creation_date": str(datetime.datetime.now())
    }
    with open("config.json", "w") as f:
        json.dump(config, f, indent=4)
    print("Default configuration created")

 

Installing and using third-party modules

Beyond the standard library, the Python ecosystem has hundreds of thousands of third-party modules available on PyPI (Python Package Index). You install them with pip:

PYTHON
# Installation from the terminal
pip install requests
pip install numpy pandas
pip install flask

Once installed, a third-party module is used exactly like a built-in module:

PYTHON
import requests

response = requests.get("https://api.github.com")
if response.status_code == 200:
    data = response.json()
    print(f"GitHub API accessible")
else:
    print(f"Error: {response.status_code}")
Good to know

It is recommended to use a virtual environment (venv) to isolate each project's dependencies. This prevents version conflicts between your different projects.

 

How Python finds modules

When you write import my_module, Python looks for the module in a specific order:

  1. The module cache: if the module has already been imported, Python retrieves it from sys.modules.
  2. Built-in modules: Python checks if it is a built-in module (like sys or math).
  3. The search path sys.path: Python goes through the directories listed in sys.path, which includes:
    • The directory of the currently running script
    • The directories defined by the PYTHONPATH environment variable
    • The default installation directories (site-packages)

You can inspect the search path:

PYTHON
import sys

for path in sys.path:
    print(path)

And even add a custom directory:

PYTHON
import sys
sys.path.append("/path/to/my/modules")

import my_custom_module

 

Best practices for modules

To write clean and maintainable Python code, here are the best practices to follow regarding modules:

  • Place all your imports at the top of the file: this is the PEP 8 convention. Imports should be grouped in this order: standard modules, third-party modules, local modules, with a blank line between each group.
  • Avoid from module import *: this syntax makes the code hard to understand and can cause name conflicts.
  • Always use the if __name__ == "__main__" pattern: this makes your modules both importable and executable.
  • Define __all__: in your public modules, use the __all__ variable to explicitly control what is exported.
  • Document your modules: add a docstring at the very beginning of the file to explain the module's purpose.
  • Name your modules in lowercase: according to PEP 8, module names should be short, lowercase, and underscores are acceptable if it improves readability.
  • Avoid circular imports: if module A imports module B and B imports A, you will get errors. Restructure your code to eliminate these cyclic dependencies.

Here is an example of a file following all these conventions:

PYTHON
"""User management module.

This module provides functions to create, read,
update and delete users.
"""

# Standard modules
import os
import json
from datetime import datetime

# Third-party modules
import requests

# Local modules
from .database import connection

__all__ = ["create_user", "get_user"]


def create_user(name, email):
    """Create a new user.
    
    Args:
        name: The user's name.
        email: The user's email address.
    
    Returns:
        dict: The created user's information.
    """
    user = {
        "name": name,
        "email": email,
        "creation_date": str(datetime.now())
    }
    return user


def get_user(identifier):
    """Retrieve a user by their identifier."""
    # Retrieval logic...
    pass


if __name__ == "__main__":
    # Quick tests
    user = create_user("Alice", "alice@example.com")
    print(user)

 

Reloading a module

When working in interactive mode (in a Python terminal or a Jupyter notebook), a module is only imported once. If you modify the source file, the changes will not be taken into account automatically. To force a reload, use importlib.reload():

PYTHON
import importlib
import my_module

# After modifying the my_module.py file
importlib.reload(my_module)

# The changes are now taken into account
my_module.my_function()
Warning

Module reloading is useful for interactive development, but it can cause unexpected behavior in complex programs. Prefer restarting your program rather than reloading modules in production.

 

Dynamic exploration of a module

Python offers several tools to explore the contents of a module at runtime:

PYTHON
import math

# List all attributes of the module
print(dir(math))

# Get help on the module
help(math)

# Get help on a specific function
help(math.sqrt)

# Check the module's file path
print(math.__file__)

# Read the module's docstring
print(math.__doc__)

The print function combined with dir() is an excellent way to quickly discover what a module has to offer.

 

Frequently asked questions

Question

What is the difference between a module and a package in Python?

A module is a single .py file containing Python code. A package is a folder containing an __init__ file and one or more modules. The package allows you to organize modules hierarchically. For example, utils/text.py is a module inside the utils package. You can think of a package as a folder of modules, and a module as an individual file.

 

Question

How do you fix the ModuleNotFoundError error?

This error means that Python cannot find the module you are trying to import. First check that the module is properly installed (with pip list for third-party modules). Then make sure your file is in a directory listed in sys.path. If you are using a virtual environment, verify that it is properly activated. Finally, check that the module name is correctly spelled — Python is case-sensitive.

 

Question

Can you import a module located in another directory?

Yes, you have several options. You can add the directory to sys.path, set the PYTHONPATH environment variable, or use relative imports within a package. The cleanest solution is to structure your project as a package with appropriate __init__.py files and install your package locally with pip install -e ..

 

Question

How can you learn to properly organize your modules in Python?

Mastering modules and Python project architecture is achieved through practice and structured learning. We recommend following our dedicated Python course on Believemy, which covers modules, packages, code organization best practices and much more in depth. You will find hands-on exercises to help you progress quickly.

Related terms

Discover our python glossary

Browse the terms and definitions most commonly used in development with Python.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.