LambdaLabTM
Computer Science · Class 11 · Python Modules
Modulesimport⏱️ 12 min read

What a Module Is

Somebody has already written a square root. Thousands of somebodies have already written a random number generator and an average. A module is a file of ready-made code you can pull into your program with one line — and Python ships with hundreds of them. This page is about that one line, because there are two spellings of it and they lead to two different ways of writing everything afterwards.

1The problem, first

Ask Python for a square root without arranging anything and it does not know what you mean:

no_import.py
print(sqrt(25))
Output
Traceback (most recent call last):
  File "no_import.py", line 1, in <module>
    print(sqrt(25))
          ^^^^
NameError: name 'sqrt' is not defined

sqrt is not a built-in like print or len. It lives in a module called math, and Python will not go looking for it unless you say so. That is deliberate: Python starts with a small set of names, and you add only what you need, so nothing you did not ask for can quietly clash with your own variables.

2Form 1 — import math

import_math.py
# bring in the whole module, and reach into it with a dot

import math

print(math.sqrt(25))
print(math.pi)
Output
5.0
3.141592653589793
Reading the dot
math.sqrt(25)

Which module it comes from, then which name inside it. The same dot you already use for name.upper() and marks.count(6) — a way of saying “this name, belonging to that thing”.

Watch Out
With this form, the module name is not optional. import math puts one new name into your program — math. It does not put pi or sqrt in, so a bare print(pi) still raises NameError: name 'pi' is not defined, even with the import sitting right above it.

3Form 2 — from math import sqrt

The other form lifts individual names out of the module and drops them straight into your program. Then there is no dot to write:

from_import.py
# take just the names you want

from math import sqrt

print(sqrt(25))
Output
5.0
from_import_many.py
# several at once, separated by commas

from math import pi, sqrt, floor

print(pi)
print(sqrt(2))
print(floor(3.9))
Output
3.141592653589793
1.4142135623730951
3
Watch Out
And now the module name is not available. from math import sqrt brings in sqrt and nothing else — not even math itself. So math.floor(3.9) after that import raises NameError: name 'math' is not defined. The two forms are mirror images: each one gives you exactly what the other does not.
You wroteThis worksThis is a NameError
import mathmath.sqrt(25)sqrt(25)
from math import sqrtsqrt(25)math.sqrt(25)

4Form 3 — import math as m

as gives the module a shorter name for the rest of the file. It changes nothing else:

import_as.py
# a nickname for the module

import math as m

print(m.sqrt(81))
print(m.pi)
Output
9.0
3.141592653589793

With a four-letter name like math this is barely worth it. It becomes a habit with longer ones — import statistics as st — and in Class 12 you will meet libraries where import pandas as pd is what everybody writes, so the nickname is effectively part of the library's name.

5from math import *, and why to avoid it

A star means “everything”, and it does work — every name in the module arrives without a dot. It is also the one form worth actively avoiding:

star_trouble.py
# your own pow() disappears under the module's

from math import *

print(pow(2, 10))
Output
1024.0

Python has a built-in pow() that answers 1024 — an integer. math has its own pow() that answers 1024.0 — a float. The star quietly replaced one with the other, and nothing in the program says so. With import math, the two never collide: pow() is the built-in and math.pow() is the module's.

Key Takeaway
The dot is not clutter — it is the information. math.sqrt(x) tells the next reader where sqrt came from. In a hundred-line program with three imports, that is worth four characters.

6Where the import goes

layout.py
# imports at the top, once, before anything else

import math

r = float(input('Radius: '))
area = math.pi * r * r

print('Area:', round(area, 2))
Output
Radius: 5
Area: 78.54

Python will accept an import anywhere — inside a loop, in the middle of the file — and it costs nothing after the first time, because a module is only really loaded once. It goes at the top anyway, so that a reader can see everything the program depends on without hunting for it.

layout.py

7The three on your syllabus

math

pi, e, sqrt(), pow(), fabs(), ceil(), floor(), sin(), cos(), tan()

Anything you would need a calculator for.

random

random(), randint(), randrange()

Dice, lotteries, test data, games.

statistics

mean(), median(), mode()

The three averages, on a list or a tuple.

One page each from here. They are all imported the same way, and nothing on those pages changes what this page said.

8Recap

A module is a file of ready-made code

Python ships with hundreds and loads none of them until you ask. That is why sqrt(25) is a NameError on its own.

import math → math.sqrt(25)

One new name arrives: math. Everything inside it is reached through the dot.

from math import sqrt → sqrt(25)

Just that name arrives, with no dot needed — and math itself does not, so math.floor() would be a NameError.

Avoid from math import *

It can quietly replace a built-in — math.pow gives 1024.0 where the built-in pow gives 1024 — and hides where each name came from.

✍️ Now write these yourself
  1. 1

    Print the square root of 144 twice — once with each import form.

    Hint · import math then math.sqrt(144); and from math import sqrt then sqrt(144).

  2. 2

    Write import math and then a bare print(pi), and read the error carefully.

    Hint · NameError: name 'pi' is not defined. The import brought in math, not the names inside it.

  3. 3

    Import math under the nickname m and print the area of a circle of radius 3.

    Hint · import math as m, then m.pi * 3 * 3. Round it to two decimals.

Quick Check

After `import math`, what does a bare `print(sqrt(25))` do?

Quick Check

After `from math import sqrt`, what does `math.floor(3.9)` do?

Quick Check

Why is `from math import *` worth avoiding?