A module in Python is a file containing reusable code. Once you understand modules, you can stop rewriting the same functions over and over — and start pulling in thousands of ready-made tools that ship with Python itself.
When you start writing Python, everything goes into one file. That works fine for short scripts. As programs grow, though, a single file becomes hard to navigate and maintain. Modules solve this by letting you split code into separate files, then load what you need on demand. Python has used this system since its earliest versions, and the entire ecosystem — from the standard library to third-party packages — is built on top of it.
What Is a Module?
A module is a plain Python file with a .py extension. That is the entire definition. Any file you write — greetings.py, calculator.py, utils.py — is already a module. When another Python script imports that file, Python runs the file, stores its names (functions, classes, variables), and makes them available through a module object.
The module object acts like a container. Every name defined inside the file is an attribute of that container. You reach those attributes through dot notation: module.name.
Python looks for modules in a specific set of locations called the module search path. When you import a module, Python checks the current directory first, then any directories listed in the PYTHONPATH environment variable, and finally the standard library directories bundled with your Python installation.
Creating your first module
Suppose you save the following code in a file named greetings.py:
# greetings.py
def say_hello(name):
return f"Hello, {name}!"
def say_goodbye(name):
return f"Goodbye, {name}. See you next time."
DEFAULT_GREETING = "Hi there!"
In another file in the same directory, you can load everything from greetings.py with a single line:
# main.py
import greetings
print(greetings.say_hello("Jordan"))
# Output: Hello, Jordan!
print(greetings.DEFAULT_GREETING)
# Output: Hi there!
The __name__ attribute
Every module has a built-in attribute called __name__. When you run a file directly from the terminal, Python sets __name__ to the string '__main__'. When the same file is imported by another script, Python sets __name__ to the module's filename (without the .py extension). This lets you write code that behaves differently depending on how the file is used:
# greetings.py
def say_hello(name):
return f"Hello, {name}!"
if __name__ == "__main__":
# This block only runs when you execute greetings.py directly.
# It does NOT run when greetings is imported elsewhere.
print(say_hello("World"))
Using the if __name__ == "__main__": guard is considered good practice. It keeps your test or demo code from running every time another file imports your module.
Build the correct statement to import the greetings module and call its say_hello function with the argument "Sam":
import greetings, functions stay inside the module's namespace. You access them with greetings.say_hello("Sam") — the module name comes first, followed by a dot, then the function name and its arguments. The token from belongs to a different import style: from greetings import say_hello, which would let you call say_hello("Sam") directly.
Importing Modules: Three Ways to Do It
Python gives you several import styles. Each one puts names into your script's namespace differently. Choosing the right style affects readability and whether name collisions can occur.
Style 1 — import module_name
The simplest form. The entire module loads and is accessible through its name.
import math
result = math.sqrt(49) # 7.0
pi_value = math.pi # 3.141592653589793
print(result)
print(pi_value)
Style 2 — from module_name import name
Imports only one specific name. That name lands directly in your local namespace, so you skip the module prefix.
from math import sqrt, pi
result = sqrt(49) # No math. prefix needed
print(pi) # 3.141592653589793
Style 3 — import module_name as alias
Gives the module a shorter or more convenient name. This is common in data science and scientific computing communities.
import random as rng
number = rng.randint(1, 100)
print(number) # A random integer between 1 and 100
Avoid from module import * in production code. It dumps every name from a module into your namespace without showing you which names came from where, making bugs harder to trace.
The table below summarizes the three approaches side by side:
- Usage
- math.sqrt(9)
- Namespace
- Names stay inside the module object. No collision risk.
- Usage
- sqrt(9)
- Namespace
- The name sqrt lands directly in your local namespace. Can collide if you define your own sqrt.
- Usage
- m.sqrt(9)
- Namespace
- Module is aliased. Useful for long module names or community conventions like import numpy as np.
The Python Standard Library
Python ships with a large collection of ready-to-use modules called the standard library. No installation is needed — every module in it is available the moment Python is installed on a machine. The official documentation describes it as offering a wide range of facilities for working with the operating system, networking, data formats, mathematics, and more.
The table below highlights some frequently used standard library modules that beginners encounter early:
- Purpose
- Mathematical functions: sqrt, floor, ceil, log, trigonometry, and constants like pi and e.
- Example
- math.ceil(4.2) returns 5
- Purpose
- Random number generation, shuffling lists, picking random elements.
- Example
- random.choice(["red", "blue", "green"]) picks one string at random
- Purpose
- Operating system interaction: file paths, environment variables, directory listing.
- Example
- os.getcwd() returns your current working directory as a string
- Purpose
- Working with dates and times: creating date objects, calculating differences, formatting output.
- Example
- datetime.date.today() returns today's date
- Purpose
- Encoding Python objects as JSON strings and decoding JSON back into Python objects.
- Example
- json.dumps({"key": "value"}) returns the string '{"key": "value"}'
Here is a short example that uses three standard library modules together:
import math
import random
import datetime
# Pick a random number and compute its square root
number = random.randint(1, 100)
root = math.sqrt(number)
# Get today's date
today = datetime.date.today()
print(f"Date: {today}")
print(f"Random number: {number}")
print(f"Square root: {root:.4f}")
The code below tries to use the math module to compute a square root and round the result. One line contains a bug. Click the line you think is wrong, then hit check.
result = math.sqrt(number). Because the script uses import math (not from math import sqrt), the name sqrt is not in the local namespace. You must access it through the module: math.sqrt(). Without the math. prefix, Python raises a NameError because it cannot find a name called sqrt.
How to Use Modules in Python
Follow these four steps any time you want to use a module — whether it comes from the standard library or from a file you wrote yourself.
-
Choose a module from the standard library
Identify the functionality you need. Python's standard library covers math, random numbers, file paths, dates, and much more. Browse the official documentation at docs.python.org/3/library/ to find the right module for your task.
-
Write an import statement at the top of your file
Add
import module_nameat the top of your Python script, before any other code that uses the module. For example, writeimport mathorimport random. Convention places all imports together at the top of the file. -
Access the module's functions and variables with dot notation
Use
module_name.function_name()to call functions ormodule_name.CONSTANTto read values. For example,math.sqrt(25)returns5.0, andmath.pigives you the value of pi. The dot operator tells Python to look inside the module's namespace. -
Use from import to bring specific names into your namespace
If you only need one or two names from a module, write
from module_name import name. This lets you call the function directly without a prefix. For example,from math import sqrtmeans you writesqrt(25)instead ofmath.sqrt(25). Be cautious with common names that could shadow other definitions.
Python Learning Summary Points
- A module is any
.pyfile. Its functions, classes, and variables become attributes of a module object that you access with dot notation after importing. - Python provides three main import styles:
import module,from module import name, andimport module as alias. The first is the safest choice for beginners because it keeps names organized inside their module's namespace. - The standard library ships with Python and requires no installation. Start with
math,random,os,datetime, andjson— these cover a wide range of common tasks and appear frequently in beginner-to-intermediate Python code. - The
if __name__ == "__main__":guard prevents code from running automatically when a file is imported. Use it to separate a module's reusable code from test or demonstration logic. - Namespaces protect your code from accidental name collisions. Every module has its own namespace, and
import modulekeeps that namespace separate from your script's globals.
Modules are the foundation of every Python project beyond a single script. Once you are comfortable with the import system, the entire standard library — and the thousands of third-party packages available through pip — becomes accessible to your programs.
Frequently Asked Questions
A module in Python is a file containing Python code — functions, classes, and variables — that you can reuse in other programs. Every Python file with a .py extension can act as a module. Modules help you organize code into logical units and avoid rewriting the same logic in multiple places.
You import a module using the import keyword followed by the module name. For example, import math gives you access to everything inside the math module. You then call its contents with dot notation, such as math.sqrt(16). You can also use from math import sqrt to import only a specific name.
import math loads the entire module and requires you to use math.sqrt() to call functions. from math import sqrt imports only the sqrt function into your local namespace, letting you call sqrt() directly without the prefix. Both work, but from import can lead to name collisions if two modules define the same name.
The Python standard library is the large collection of modules that ships with every Python installation. It includes modules for math, file operations, dates and times, random number generation, networking, JSON handling, and much more. You can use any standard library module with a plain import statement — no additional installation required.
Save Python code in a .py file. For example, if you save functions inside a file named greetings.py, you can import it in another file in the same directory with import greetings. Python will execute that file and make its names available through the module object.
The as keyword creates an alias for a module. Writing import numpy as np means you can use np instead of numpy throughout your code. Aliases are commonly used for modules with long names or to follow community conventions such as import pandas as pd.
A namespace is a container that maps names to objects. When you import a module, Python creates a separate namespace for it so that its names do not clash with names in your own script. Accessing math.pi uses the dot operator to look up pi inside the math module's namespace rather than in your script's global namespace.
Every Python module has a built-in __name__ attribute. When a file runs directly, __name__ is set to the string '__main__'. When the same file is imported as a module, __name__ is set to the module's filename without the .py extension. The pattern if __name__ == '__main__': is used to run code only when a file is executed directly, not when it is imported.