Python modules: import styles, aliases, reload, random and __name__
Advertisement
A module is simply a Python file whose code another file can reuse. The standard library ships hundreds of them (math, random, datetime, json), pip installs thousands more, and every .py file you write is a module too. Learning to import them well is the step that takes you from writing scripts to building programs out of parts. This post covers the import styles, aliases, inspecting a module, reloading it, the random module and the special __name__ variable. Every output below was produced on a real interpreter (Python 3.9).
Why use modules
A module gives you three things. First, reuse: you write a function once and import it everywhere. Second, organisation: a 2,000-line script becomes five files of 400 lines, each about one topic. Third, separate names: a variable called total in one module does not clash with a total in another, because each module has its own namespace.
The four ways to import
Suppose we use the math module:
import math
print(math.sqrt(16), math.pi) # 4.0 3.141592653589793
from math import sqrt, pi
print(sqrt(16), pi) # 4.0 3.141592653589793
import math as m
print(m.floor(2.7)) # 2
from math import factorial as fact
print(fact(5)) # 120
| Style | You write | Use it when |
|---|---|---|
import math |
math.sqrt(x) |
The default. It is always clear where a name comes from. |
from math import sqrt |
sqrt(x) |
You use one or two names many times. |
import math as m |
m.sqrt(x) |
The module name is long (import numpy as np is a convention). |
from math import * |
sqrt(x) |
Almost never. It floods your namespace and hides where names come from. |
Module aliasing
import module as alias renames the module in your file only. After import math as m, the name math is no longer defined in your program:
import math as m
try:
math
except NameError as e:
print(e) # name 'math' is not defined
This is a common surprise: the alias replaces the name, it does not add a second one.
Member aliasing
from module import name as other does the same for one member. It is useful when two modules offer the same name, or when the original name is awkward:
from math import sqrt as root
from cmath import sqrt as complex_root
print(root(9), complex_root(-9)) # 3.0 3j
You can import several members in one line, from math import sqrt, ceil, floor, and the brackets let you split a long list over lines.
What is inside a module
Two built-in functions help you explore:
import math
names = [n for n in dir(math) if not n.startswith("_")]
print(len(names) > 40, "sqrt" in names, "gcd" in names) # True True True
print(math.sqrt.__doc__.splitlines()[0]) # Return the square root of x.
dir(module) lists every name in the module. help(math.sqrt) prints the documentation in the console. Special attributes tell you more:
print(math.__name__, math.sqrt.__name__) # math sqrt
import os
print(os.__file__.endswith("os.py")) # True
module.__file__ shows where the source lives (built-in modules written in C, like math on some systems, have none). Reading the source of a standard-library module is one of the best ways to improve.
Python runs a module once
The first import runs the file from top to bottom and stores the result in a cache called sys.modules. Later imports reuse it. We can prove this with a small module:
# hello.py
print("loading hello")
value = 1
def greet():
return "hi"
import hello # prints: loading hello
import hello # prints nothing: already loaded
import sys
print("hello" in sys.modules) # True
Running the second import prints nothing, because Python found hello in sys.modules. This is why top-level code in a module (like a connection to a database) runs only once per program.
Reloading a module
If you change hello.py while a program or an interactive session is running, import hello will not pick up the change, because of the cache. To force it, use importlib.reload:
import importlib
import hello
# ... edit hello.py so that value = 2 ...
importlib.reload(hello) # runs the file again
print(hello.value) # 2
Reloading is mostly a tool for interactive work and notebooks. It has a catch: objects created from the old version keep the old code, and names imported with from hello import value are not updated. In a normal program, you simply restart it.
The random module
random is the module most beginners meet first, and it shows several import ideas at once.
import random
random.seed(7) # makes the results repeatable
print(random.random()) # 0.32383276483316237
print(random.randint(1, 10)) # 3
print(random.choice(["a", "b", "c"]))
The numbers above come from seed(7) on Python 3.9; with a different seed (or none) you get different values, which is the point. Here is the full set you will use:
| Function | What it does |
|---|---|
random.random() |
a float from 0.0 up to, but not including, 1.0 |
random.uniform(a, b) |
a float between a and b |
random.randint(a, b) |
an integer from a to b, both included |
random.randrange(a, b, step) |
like range: the end is excluded |
random.choice(seq) |
one item from a sequence |
random.choices(seq, k=3) |
k items, with repetition |
random.sample(seq, k) |
k different items, without repetition |
random.shuffle(list) |
shuffles a list in place and returns None |
import random
random.seed(1)
deck = list(range(1, 6))
random.shuffle(deck)
print(sorted(deck)) # [1, 2, 3, 4, 5] (same items, new order)
print(len(random.sample(range(100), 5))) # 5
Two warnings. The random module is not secure: it must never generate passwords, tokens or anything an attacker could benefit from guessing. For that, use the secrets module. The Password Generator on this site uses the browser's secure generator for the same reason. And never name your own file random.py: Python would import your file instead of the library, and you would get confusing errors.
The special variable __name__
Every module has a built-in variable called __name__. When Python runs a file directly, it sets __name__ to the string "__main__". When another file imports it, __name__ is the module's name. That lets a file work as both a library and a program:
# calc.py
def add(a, b):
return a + b
print("name is", __name__)
if __name__ == "__main__":
print(add(2, 3))
Running python3 calc.py printed:
name is __main__
5
Importing it from another file (import calc) printed only name is calc, and the add(2, 3) demo did not run. Put your demo or main() call under this check so that importing the file never starts the program by accident. The packages post shows how __name__ behaves inside a package.
Where Python finds modules
When you write import x, Python looks at the built-in modules first, then the folders listed in sys.path: the folder of the script you ran, the folders in the PYTHONPATH variable, and the folders where Python and pip install libraries. If the module is in none of them, you get:
try:
import nothere
except ModuleNotFoundError as e:
print(e) # No module named 'nothere'
The fixes are, in order of likelihood: check the spelling, run pip install for the package, make sure you run the program from the right folder, and make sure the virtual environment you installed into is the one that is active.
Useful standard modules to know
| Module | Typical use |
|---|---|
math |
square roots, logarithms, trigonometry, gcd, factorial |
random |
random numbers, shuffling, sampling |
datetime |
dates, times and differences between them |
os and pathlib |
files, folders, environment variables |
sys |
arguments, the path, exiting a program |
json |
reading and writing JSON |
re |
regular expressions |
logging |
log messages |
collections |
Counter, namedtuple, deque |
Common mistakes
- Naming your own file after a library (
random.py,json.py,math.py) so it shadows the real one. - Using
from module import *and not knowing where a name came from. - Expecting
import x as yto leavexdefined. - Expecting a second
importto re-run an edited file. - Using
randomfor security. - Putting program start-up code at the top level instead of under
if __name__ == "__main__":.
Practice
Create shapes.py with functions area_circle(r) and area_rect(w, h), using math.pi. Add a demo under the __name__ check. Import it from a second file in three different styles, and print the area of a circle with radius 3. Then write a small dice game: roll two dice with random.randint ten times and count how often the total is 7.
Continue
Modules group code in one file; packages group modules in folders. Next, look at functions, the units that modules contain, and see the language fundamentals post for the types you will use. The Python video course covers the same topics step by step, and the Python cheat sheet summarises the import forms.