Skip to content

Modules and imports

~15 min ยท prerequisite: Recursion basics

What you will be able to do

  • Import a module from Python's standard library with import, and use its functions.
  • Import a single name with from ... import, and rename an import with as.
  • Split code into your own module file, and import it from another file.

The idea

A module is a file that holds Python code, such as functions and values. Its file name ends in .py, and its name is the file name without that ending. Keeping related code in a module lets you reuse it in other programs without copying it.

Python ships with many modules already installed. These are the standard library. One example is math, which holds functions such as sqrt for square roots, and values such as pi. To use a module, you write import followed by its name. The names inside the module are then reached with a dot, such as math.sqrt. The dot means "the name sqrt that belongs to math".

Think of a module as a toolbox. You open the box with import, and then reach for the tool you need, using its label. Each module has its own names, so math.sqrt and a function of your own called sqrt do not clash.

You can also import one name directly with from math import sqrt. Then you write sqrt(16) without the module name. You can rename an import with as, as in import math as m, and then write m.sqrt. Both forms are valid. The dotted form is used in most of this course, because the module name shows where each function comes from.

When Python runs an import line for a module it has not loaded yet, it runs that module's code once, and keeps the result. Later imports of the same module reuse it.

To write your own module, save functions in a file, such as greetings.py. Another file in the same folder can then run from greetings import hello. When you run a file directly, Python sets the special name __name__ to "__main__". When the same file is imported, __name__ holds the module's name instead. This lets a file hold a demo under if __name__ == "__main__":, which runs only when you run that file itself.

Worked example

import math

print(math.sqrt(16))
print(math.pi > 3.14)

Expected output:

4.0
True

Line by line, this is what Python does:

  1. import math loads the standard library module named math, and binds the name math to it.
  2. math.sqrt(16) calls the function sqrt that belongs to math. The result is the float 4.0, because sqrt always returns a float.
  3. print shows 4.0 on the first line.
  4. math.pi > 3.14 compares the constant pi with 3.14. The comparison is True, and print shows it.

Try it

The first block uses three functions from math. The second block imports one name and renames it. The third block combines an import with a function of your own.

import math

assert math.sqrt(16) == 4.0
assert math.floor(2.7) == 2
assert math.ceil(2.1) == 3
from math import factorial as fact

assert fact(4) == 24
import math


def area_of_circle(radius):
    return math.pi * radius * radius


assert math.isclose(area_of_circle(1), 3.14159, rel_tol=1e-4)

Two files work together like this. Save the first as greetings.py, and the second as main.py, in the same folder.

# greetings.py
def hello(name):
    return "Hello, " + name


if __name__ == "__main__":
    print(hello("module demo"))
# main.py
from greetings import hello

print(hello("Ada"))

Running python3 main.py in that folder prints Hello, Ada. Running python3 greetings.py prints Hello, module demo. The second message appears only when the file runs directly.

Common mistakes

  1. Misspelling a module name. The following line has an extra letter:

    import maths
    

    Python reports:

    ModuleNotFoundError: No module named 'maths'
    

    Check the spelling. The standard library module is math.

  2. Using a function without importing it. The following line calls sqrt without writing math. in front:

    import math
    
    print(sqrt(16))
    

    Python reports:

    NameError: name 'sqrt' is not defined
    

    Write math.sqrt(16), or import the name with from math import sqrt.

  3. Calling a name that is not in the module. The following line uses a function that math does not have:

    import math
    
    print(math.square(3))
    

    Python reports:

    AttributeError: module 'math' has no attribute 'square'
    

    Check the spelling in the documentation. Multiplying 3 * 3 also gives the square.

  4. Calling a module as if it were a function. The following line puts parentheses after the module name:

    import math
    
    print(math(4))
    

    Python reports:

    TypeError: 'module' object is not callable
    

    Call a function inside the module instead, such as math.sqrt(4).

Practice

  1. Use math.sqrt to show that math.sqrt(81) equals 9.0. Write an assert for it.
  2. Use from math import pi, and assert that round(pi, 2) equals 3.14.
  3. Define hypotenuse(a, b) using import math as m, and return m.sqrt(a * a + b * b). Assert that hypotenuse(3, 4) equals 5.0.
  4. Define lcm(a, b) that returns the least common multiple, using from math import gcd and the formula a * b // gcd(a, b). Assert that lcm(4, 6) equals 12 and that lcm(7, 3) equals 21.
  5. Stretch: use from math import comb. Define count_routes(rows, cols) that returns comb(rows + cols - 2, rows - 1), the number of paths that go right or down across a grid. Assert that count_routes(2, 2) equals 2, and that count_routes(3, 3) equals 6.
Solution
  1. ```python import math

assert math.sqrt(81) == 9.0 ```

  1. ```python from math import pi

assert round(pi, 2) == 3.14 ```

  1. ```python import math as m

def hypotenuse(a, b): return m.sqrt(a * a + b * b)

assert hypotenuse(3, 4) == 5.0 ```

  1. ```python from math import gcd

def lcm(a, b): return a * b // gcd(a, b)

assert lcm(4, 6) == 12 assert lcm(7, 3) == 21 ```

  1. ```python from math import comb

def count_routes(rows, cols): return comb(rows + cols - 2, rows - 1)

assert count_routes(2, 2) == 2 assert count_routes(3, 3) == 6 ```

Recap

  • import math gives you the module, and you reach its names with a dot, such as math.sqrt.
  • from module import name brings in one name, and as gives an import a new name.
  • Your own module is a .py file. Use if __name__ == "__main__": for code that should run only when that file is run directly.

Sources