So far, you've been using Python's built-in functions and libraries. But what if you create code that you want to reuse across multiple projects, or share with others? That's where creating your own modules comes in! A Python module is simply a file containing Python definitions and statements. The file name is the module name with the suffix .py appended. Think of it as a custom toolbox for your Python code.
Let's start by creating a simple module. Imagine you're building a calculator and want to have separate functions for addition, subtraction, multiplication, and division. We can put these into a file named calculator.py.
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
return "Error: Division by zero!"
return a / bNow that we have our calculator.py file, we can use it in another Python script. To do this, we use the import statement. You can import the entire module, or specific functions from it.
Here's how you would import and use our calculator module in a separate file (let's call it main_app.py):
import calculator
result_add = calculator.add(10, 5)
print(f"10 + 5 = {result_add}")
result_divide = calculator.divide(20, 4)
print(f"20 / 4 = {result_divide}")
result_divide_by_zero = calculator.divide(10, 0)
print(f"10 / 0 = {result_divide_by_zero}")When you run main_app.py, you'll see the results of the calculations. The import calculator line tells Python to look for a file named calculator.py (or a compiled version of it) in the same directory or in its search path and make its contents available.
You can also import specific functions using from ... import .... This can make your code slightly more concise, as you don't need to prefix the function calls with the module name.
from calculator import add, multiply
result_add_direct = add(7, 3)
print(f"7 + 3 = {result_add_direct}")
result_multiply_direct = multiply(6, 2)
print(f"6 * 2 = {result_multiply_direct}")Using from ... import ... is great for commonly used functions. However, if you import many functions this way, it might become unclear where a particular function originated from, especially in larger projects. A common practice to avoid this ambiguity is to use an alias for your module.
import calculator as calc
result_sub = calc.subtract(15, 7)
print(f"15 - 7 = {result_sub}")This import calculator as calc line imports the calculator module but allows you to refer to it using the shorter alias calc. This is especially useful for modules with long names or to avoid naming conflicts.
You can even import all names from a module using from module import *. However, this is generally discouraged in production code because it can pollute your namespace (introduce many names into your current scope) and make it very hard to track where functions and variables come from. It's best to be explicit.
Let's consider how Python finds your modules. When you type import my_module, Python searches for my_module.py in the following locations, in order:
- The directory containing the input script (or the current directory if running interactively).
- The list of directories contained in the
PYTHONPATHenvironment variable. - The installation-dependent default directories.
This means that for your own modules, the simplest way to make them importable is to keep them in the same directory as the script that imports them. As your projects grow, you might organize your modules into packages (which are directories containing modules and an __init__.py file), but that's a topic for a later chapter!
graph TD
A[Create calculator.py file]
B[Define functions: add, subtract, multiply, divide]
C[Create main_app.py file]
D[Import calculator module]
E[Use functions from calculator module]
F[Run main_app.py]
A --> B
C --> D
D --> E
E --> F