Modules and Packages
As your code grows, putting everything into one file becomes unwise. Modules let you split code into multiple files; packages let you organize related modules together. Learning modular programming is the threshold to true "engineering."
1. What is a Module
In Python, a .py file is a module. You can use import to bring in functionality from other modules:
Example: Importing Standard Library Modules
# Import an entire module
import math
print(math.pi) # 3.141592653589793
print(math.sqrt(16)) # 4.0
# Import a specific function
from random import randint
print(randint(1, 10)) # Random integer between 1 and 10
# Import multiple items
from datetime import datetime, timedelta
now = datetime.now()
print(now) # Current time
Python comes with a large collection of standard library modules — math, random, datetime, os, json... They are already there when you install Python, just import and use.
Tip: The standard library is one of Python's biggest advantages: "Batteries Included" is Python's philosophy — most everyday functionality is already provided by the standard library, no extra installation needed.
2. Custom Modules
Creating a module is simple — just write a .py file.
my_tools.py
# This is a custom module: my_tools.py
def greet(name):
return f"Hello, {name}"
def add(a, b):
return a + b
PI = 3.14159
main.py (using the module)
Example: Importing and Using a Custom Module
# Import custom module
import my_tools
print(my_tools.greet("Zhang San")) # Hello, Zhang San
print(my_tools.add(5, 3)) # 8
print(my_tools.PI) # 3.14159
Warning: Custom module files must be in the same directory as the file calling them, or in Python's search path. The most common beginner mistake is getting "ModuleNotFoundError" when importing their own modules — check the file path.
3. if __name__ == "__main__"
This is a very important Python pattern — it lets a file work both as an importable module and as a directly runnable script:
Example: if name Dual-Purpose Pattern
# calculator.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
# The code below only runs when this file is executed directly
if __name__ == "__main__":
print("Testing calculator functions:")
print(f"3 + 5 = {add(3, 5)}")
print(f"10 - 4 = {subtract(10, 4)}")
When you:
python calculator.py-> test code runs (__name__ == "__main__"is True)import calculatorin another file -> test code does NOT run (__name__is"calculator")
Tip: Every Python file has a
__name__variable. When run directly, it's"__main__"; when imported, it's the module name. This feature lets the same file serve dual purposes as both a "library" and a "script."
4. Packages
When you have many modules, use packages to organize them — a package is a directory containing an __init__.py file:
my_package/
├── __init__.py ← This file is required (can be empty)
├── math_tools.py
└── string_tools.py
# math_tools.py
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
return "Cannot divide by zero"
return a / b
# string_tools.py
def reverse(text):
return text[::-1]
def count_vowels(text):
vowels = "aeiouAEIOU"
return sum(1 for c in text if c in vowels)
Example: Using Modules from a Package
# Use the package
from my_package import math_tools, string_tools
print(math_tools.multiply(3, 5)) # 15
print(string_tools.reverse("Python")) # nohtyP
5. Third-Party Libraries and pip
Python's power comes largely from its rich ecosystem of third-party libraries. Install them with pip:
pip install requests # HTTP requests library
pip install numpy # Numerical computation
pip install pandas # Data analysis
pip install flask # Web framework
requirements.txt
When sharing your project with others, you need to tell them which third-party libraries are required. requirements.txt is for this purpose:
requests==2.31.0
numpy==1.24.0
pandas==2.0.0
flask==3.0.0
The recipient can install all dependencies with one command:
pip install -r requirements.txt
Generating requirements.txt
pip freeze > requirements.txt
Tip: Project convention: Any project that uses third-party libraries should have a
requirements.txtin the root directory. This is a basic Python project convention. Even if library versions update,pip install -r requirements.txtwill install the exact versions you used, ensuring compatibility.
Common Use Cases
- Code reuse: Extract utility functions into separate modules, shared across multiple projects.
- Project organization: Use packages to organize by functionality (e.g.,
models/,utils/,views/). - Dependency management: Use
requirements.txtto manage third-party library versions. - Dual-purpose scripts: Use
if __name__ == "__main__"so a file can be both imported and run directly.
FAQ
import math and from math import pi?import math imports the entire module; you must write math.pi to use it. from math import pi imports only pi; you can use pi directly. The former is clearer (you know where pi comes from); the latter is more concise. There's no universal standard, but consistency within a file is recommended.__init__.py have to be empty?__init__.py executes when the package is imported. You can put initialization code there — define __all__ to control from package import * behavior, or even write utility functions directly in it. In most simple projects, __init__.py is indeed empty.pip install put installed libraries?Lib/site-packages/ directory under your Python installation. If you have projects with different dependency requirements, use virtual environments (venv) — each project has its own dependency directory, keeping them isolated. Create one with python -m venv myenv, activate with source myenv/bin/activate.Summary
- A
.pyfile is a module; useimportto use it from module import nameimports only specific itemsif __name__ == "__main__"lets a file be both a module and a script- A package is a directory with
__init__.pyfor organizing multiple modules pip install package_nameinstalls third-party librariesrequirements.txtrecords project dependencies;pip install -r requirements.txtinstalls them all at once
Exercises
-
Beginner (Difficulty: Star): Create a module
geometry.pywith two functions:circle_area(radius)andrectangle_area(width, height). Then import and use them in another file. -
Intermediate (Difficulty: Star-Star): Add an
if __name__ == "__main__"block togeometry.pyto test your functions. Verify: running directly executes tests; importing skips them. -
Advanced (Difficulty: Star-Star-Star): Create a package
string_utils/with two modules:validators.py(validation functions:is_email(),is_phone()) andtransformers.py(transformation functions:to_snake_case(),to_camel_case()). Write a test script outside the package to import and use these features.



