Table of Contents
Why importing matters
Python becomes much more powerful when you use modules: files (or packages) that contain extra functions, classes, and variables you can use in your own programs.
In this chapter, you’ll learn the different ways to import modules and how those choices affect how you write and read code.
We’ll use the standard library modules like math and random for examples, but the focus here is how to import, not what each module does.
The basic `import` statement
The simplest way to use a module is:
import math
print(math.sqrt(16))
print(math.pi)What happens:
- Python loads the
mathmodule. - You get a module object called
math. - You access everything inside it using
module_name.something, e.g.math.sqrt,math.pi.
General pattern:
import module_name
result = module_name.function_name(arguments)
value = module_name.variable_nameYou can import multiple modules on one line:
import math, random
print(math.pi)
print(random.randint(1, 10))This is valid, but many style guides prefer one module per line for readability:
import math
import randomImporting with an alias: `import ... as ...`
Sometimes module names are long, or you want a shorter, more convenient name. Use as:
import math as m
print(m.sqrt(25))
print(m.pi)You can also alias other modules:
import random as rnd
num = rnd.randint(1, 6)
print(num)This does not change the module itself, only the name you use in your code.
Why aliases are useful:
- Shorter to type (e.g.
import numpy as npis common in data science). - Can avoid name conflicts (if you already have a variable called
random, you might doimport random as rnd).
Importing specific names: `from module import name`
If you only need a few things from a module, you can import them directly:
from math import sqrt, pi
print(sqrt(16))
print(pi)Notice:
- You don’t write
math.sqrtormath.pianymore. sqrtandpiare now available as if they were defined in your file.
General pattern:
from module_name import name1, name2, name3
result = name1(...)You can also use aliases with this form:
from math import sqrt as square_root, pi as PI
print(square_root(9))
print(PI)This is helpful when:
- You want shorter or clearer names.
- You want to avoid confusion (for example, if you have your own
pivariable).
`import module` vs `from module import ...`
Both forms work, but they have different trade-offs.
`import module`
import math
print(math.sqrt(9))Pros:
- Very clear where functions and values come from (
math.sqrtis obviously frommath). - Less chance of name conflicts with your own variables or functions.
- Often preferred in larger projects for readability.
Cons:
- Slightly longer to type (
math.sqrtvssqrt).
`from module import name`
from math import sqrt
print(sqrt(9))Pros:
- Less typing.
- Code can be a bit cleaner when you use the same function many times.
Cons:
- Easier to have name conflicts:
- If you have your own
sqrtfunction, this import will overwrite it. - Sometimes harder to see where a name comes from, especially in longer files.
A common beginner-friendly approach:
- Use
import modulefor general use, especially as you learn. - Use
from module import somethingwhen: - You really use that function a lot, and
- It doesn’t cause name confusion.
Importing everything: `from module import *` (and why to avoid it)
You may see:
from math import *
This imports all public names from math into your current file. After this, you can directly use sqrt, pi, cos, etc., without math..
Example:
from math import *
print(sqrt(16))
print(pi)
Problems with import *:
- You can easily overwrite your own variables or functions without realizing.
- It becomes hard to know which names come from the module and which are your own.
- Makes code harder to read and debug.
Most style guides say: avoid from module import * in real programs, especially as a beginner. Use it only in short experiments or interactive sessions if you understand the risks.
Where to write import statements
Common practice is:
- Put all
importstatements at the top of the file. - After any initial comments or docstring, before any other code.
Example:
# Simple program to demonstrate imports
import math
import random as rnd
from datetime import date
today = date.today()
print("Today's date:", today)
angle = math.pi / 4
print("Random number:", rnd.random())
print("cos(angle) =", math.cos(angle))Why:
- Easier to quickly see which modules your script needs.
- Python loads modules once, at the beginning, which is efficient.
Importing your own modules (files)
You are not limited to built-in or installed modules. A Python file you write can also be used as a module.
Suppose you have two files in the same folder:
helpers.py:
def greet(name):
print(f"Hello, {name}!")
PI = 3.14159
main.py:
import helpers
helpers.greet("Alice")
print(helpers.PI)Here:
helpers.pyis your own module.- In
main.py,import helpersgives you access to everything defined inhelpers.py.
You can also import specific names:
from helpers import greet, PI
greet("Bob")
print(PI)Important:
- The filename is the module name (without
.py). - Both files need to be in the same folder (or in a place Python can find, which you’ll typically handle as your projects grow).
What happens when you import (once-only behavior)
When Python imports a module:
- It runs the module file from top to bottom once.
- It stores the loaded module in memory.
- If you import the same module again in the same program, Python reuses the already-loaded version instead of running the file again.
Example:
utils.py:
print("utils module is being imported")
def add(a, b):
return a + b
main.py:
import utils
import utils # imported again
print(utils.add(2, 3))Output:
utils module is being imported
5
Note that the message appears only once, even though import utils is written twice. This is normal and helpful for performance.
The `__name__ == "__main__"` pattern (very briefly)
When you start making your own modules, you might see this pattern:
def main():
print("Running main function")
if __name__ == "__main__":
main()Here’s the idea as it relates to imports:
- If you run this file directly (e.g.
python myfile.py), the code insideif __name__ == "__main__":runs. - If you import this file from another script, that block does not run.
This lets a file act both as:
- A script you can run, and
- A module you can import (without running the main script part by accident).
You’ll use this more when you start structuring bigger programs.
Import errors and how to handle them
If Python can’t find a module, you’ll see an error:
import not_a_real_moduleError message:
ModuleNotFoundError: No module named 'not_a_real_module'Common reasons:
- You misspelled the module name.
- You’re trying to import a module that isn’t installed yet.
- For your own files: the file isn’t in the same folder, or Python can’t see the package.
For standard library modules like math, random, datetime, you don’t need to install anything; they come with Python. For external modules, you’ll use tools like pip (covered elsewhere) to install them before importing.
Summary
- Use
import moduleto bring in a whole module and access it withmodule.name. - Use
import module as aliasto create a shorter or clearer name. - Use
from module import nameto import specific functions or values directly. - Avoid
from module import *in real programs because it can cause confusion and name conflicts. - Keep imports at the top of your file.
- Your own
.pyfiles can be imported as modules by other files. - A module is executed once when first imported; later imports reuse the loaded module.
- If you see
ModuleNotFoundError, check spelling or whether the module is installed and accessible.