Web Analytics

Modules

Intermediate ~25 min read

Modules are the building blocks of Python's code organization. A module is simply a Python file containing functions, classes, and variables that you can reuse across projects. Instead of writing everything from scratch, you can import existing code - whether it's Python's powerful standard library or your own custom modules. This is how professional Python code stays organized, maintainable, and DRY (Don't Repeat Yourself)!

Different Ways to Import

Python offers multiple import styles, each with its own use case. You can import entire modules, specific items, or use aliases to avoid name conflicts. Understanding these patterns helps you write cleaner code and manage namespaces effectively.

Output
Click Run to execute your code
Import Best Practices: Prefer import module or from module import specific_item over from module import *. The wildcard import pollutes your namespace and makes it hard to track where names come from. PEP 8 recommends putting imports at the top of your file, grouped in order: standard library, third-party packages, then local modules.

Creating Your Own Modules

Creating a module is as simple as writing a Python file! Any .py file can be imported as a module. This lets you organize related functions and classes together, making your code reusable and maintainable. The if __name__ == "__main__" pattern is essential for writing modules that can both be imported and run directly.

Output
Click Run to execute your code
The __name__ Pattern: When a file is run directly, __name__ equals "__main__". When imported, it equals the module name. Use if __name__ == "__main__": to include test code or a main entry point that only runs when the file is executed directly, not when imported.

Packages: Organizing Multiple Modules

As projects grow, you need to organize modules into packages - directories containing multiple related modules. A package is simply a folder with an __init__.py file. This hierarchical structure enables clean imports like import mypackage.submodule and helps manage large codebases.

Output
Click Run to execute your code
Package Pitfalls: Don't name your modules the same as standard library modules (e.g., don't create random.py or math.py). Python might import your file instead of the built-in module, causing confusing errors. Also, ensure your package directories are in Python's path (sys.path) or installed properly.

Essential Built-in Modules

Python's standard library is "batteries included" - it comes with powerful modules for common tasks. The os module handles operating system interactions, sys provides system-specific parameters, random generates random numbers, and collections offers specialized container data types.

Output
Click Run to execute your code

Common Mistakes

1. Circular imports

# module_a.py
from module_b import func_b  # Imports module_b
def func_a(): return func_b()

# module_b.py
from module_a import func_a  # Tries to import module_a - CIRCULAR!
def func_b(): return func_a()

# Fix: Restructure code, use lazy imports, or import inside functions
# module_b.py (fixed)
def func_b():
    from module_a import func_a  # Import inside function
    return func_a()

2. Naming files same as standard library modules

# BAD: You created a file called random.py
# random.py
def my_random():
    return 42

# other_file.py
import random  # This imports YOUR random.py, not the standard library!
print(random.randint(1, 10))  # AttributeError: no 'randint'

# Fix: Use unique names for your modules
# my_random.py or random_utils.py instead

3. Forgetting __init__.py in packages (Python < 3.3)

# Wrong structure (pre-Python 3.3)
# mypackage/
#     module1.py   # No __init__.py!

import mypackage.module1  # ImportError!

# Correct structure
# mypackage/
#     __init__.py  # Can be empty
#     module1.py

# Note: Python 3.3+ supports implicit namespace packages,
# but explicit __init__.py is still recommended

4. Using "from module import *" and losing track of names

# Dangerous - where does 'open' come from?
from os import *
from pathlib import *

open("file.txt")  # Which 'open'? Built-in or os.open?

# Better - explicit imports
from os import getcwd, listdir
from pathlib import Path

# Or use the module prefix
import os
import pathlib
os.getcwd()
pathlib.Path(".")

5. Not understanding module search path

# Your project structure:
# project/
#     main.py
#     utils/
#         helpers.py

# In main.py - this might fail depending on how you run it
from utils.helpers import func  # Works if run from project/

# Running from different directory
# $ cd project/utils && python ../main.py
# ModuleNotFoundError!

# Fix: Use relative imports in packages, or add to sys.path
import sys
sys.path.insert(0, '/path/to/project')

# Or use -m flag: python -m main

Exercise: Create a Utility Module

Task: Create functions that could be part of a utility module.

Requirements:

  • Write a function is_even(n) that returns True if n is even
  • Write a function clamp(value, min_val, max_val) that constrains a value within bounds
  • Write a function flatten(nested_list) that flattens a nested list one level
  • Include docstrings for each function
Output
Click Run to execute your code
Show Solution
# my_utils.py - A utility module

def is_even(n):
    """Return True if n is even, False otherwise."""
    return n % 2 == 0

def clamp(value, min_val, max_val):
    """Constrain value to be within [min_val, max_val]."""
    return max(min_val, min(value, max_val))

def flatten(nested_list):
    """Flatten a nested list by one level."""
    result = []
    for item in nested_list:
        if isinstance(item, list):
            result.extend(item)
        else:
            result.append(item)
    return result

# Test the functions
if __name__ == "__main__":
    print(f"is_even(4): {is_even(4)}")
    print(f"is_even(7): {is_even(7)}")
    print(f"clamp(15, 0, 10): {clamp(15, 0, 10)}")
    print(f"clamp(-5, 0, 10): {clamp(-5, 0, 10)}")
    print(f"flatten([[1, 2], [3, 4], 5]): {flatten([[1, 2], [3, 4], 5])}")

Summary

  • Module: A Python file (.py) containing reusable code
  • Import styles: import module, from module import item, import module as alias
  • Creating modules: Just write a .py file with functions, classes, variables
  • __name__ pattern: if __name__ == "__main__": for code that runs only when executed directly
  • Package: A directory with __init__.py containing related modules
  • Standard library: os, sys, random, collections, itertools, and many more
  • Avoid: Circular imports, naming conflicts with stdlib, wildcard imports
  • Best practice: Group imports at file top: stdlib, third-party, local

What's Next?

Now that you understand how modules work, let's explore some of Python's most useful built-in modules! Next up: the datetime module for working with dates and times - essential for any application dealing with scheduling, timestamps, or time calculations.