Python Part I · Module 13 · Modules, Packages and Imports
Import Aliases
Chapter 13.2 used one keyword without explaining it, to set up a collision. That keyword renames an import as it arrives, and it has exactly one job that is genuinely necessary and several that are merely tempting. The necessary one is unavoidable and this chapter covers it first. The tempting ones are where aliases earn their bad reputation, because a name invented for the convenience of the person typing is a name that every later reader has to look up — and the convention that separates the good cases from the bad turns out to be a single question.
Foundation14 min readPythonPart IFundamentalsModulesimport
Part I · Module 13 · Chapter 13.3 · Import Aliases
1. The Keyword
as renames an import as it arrives:
import statistics as stats
print(stats.mean([1, 2, 3]))
print(stats.median([1, 5, 2]))2
2It works on both forms from Chapter 13.2:
import statistics as stats
from collections import Counter as Tally
print(stats.mean([2, 4]))
print(Tally(["a", "b", "a"]))3
Counter({'a': 2, 'b': 1})Note the second line of output: the alias changed the name you call it by, not the thing itself. Tally is still collections.Counter, and printing one still shows Counter.
2. It Renames; It Does Not Add
The consequence people meet first:
import statistics as stats
print(stats.mean([1, 2, 3]))
print(statistics.mean([1, 2, 3]))2
NameError: name 'statistics' is not definedimport statistics as stats binds one name, and it is stats. The original is not available at all.
That follows from Chapter 13.1 Section 4: an import is an assignment, and as simply says which name to assign to. There is no rule here beyond the one you already had.
3. What It Does Not Change
The alias is local to your file. It does not rename anything globally, and it does not affect what the module calls itself:
import statistics as stats
print(stats.__name__)
print(stats.mean([10, 20]))statistics
15The module still knows it is statistics. Another file importing it is entirely unaffected by what you called it here.
4. The Case Where It Is Necessary
Chapter 13.2 Section 5 showed from X import Y silently destroying a name you already had. When you genuinely need both, as is the fix:
import json
def loads(text):
"""Our own loader, which only understands comma-separated integers."""
return [int(part) for part in text.split(",")]
from json import loads as json_loads
print(loads("1,2,3"))
print(json_loads("[1, 2, 3]"))[1, 2, 3]
[1, 2, 3]Two functions called loads in spirit, both reachable, neither destroyed. Without the alias the import would have taken the name and the local function would be unreachable — with no error, as that chapter showed.
This is the use that justifies the keyword: disambiguating two things that want the same name. It happens whenever two modules export a parse, a load or an open, which is often.
5. Helpful Alias or Private Code?
The rest of the time, an alias is a choice about readability, and there is one question that settles it:
Is this alias one your reader already knows, or one you invented?
A shared alias is part of a community convention. Readers recognise it on sight, and spelling it out would actually read as unusual:
| Alias | Module | Why it is fine |
|---|---|---|
np | numpy | universal in numerical code |
pd | pandas | universal in data work |
plt | matplotlib.pyplot | universal in plotting |
None of those ship with Python, and Part I does not use them — but you will see them constantly, and recognising them is the point.
An invented alias is a private code:
import statistics as s
import json as j
from pathlib import Path as P
print(s.mean([1, 2, 3]))
print(j.dumps({"a": 1}))
print(P("logs") / "run.log")2
{"a": 1}
logs/run.logEvery line runs, and every line costs a reader a lookup. s.mean(...) three hundred lines down could be anything; statistics.mean(...) could not.
The canonical guidance for this chapter is blunt about the second form, and it is right: from pathlib import Path as P is rarely worth it — be sparing. Path is already four characters and already unmistakable. Renaming it to P saves three keystrokes once and costs a lookup every time it is read.
6. Where an Alias Genuinely Shortens Something
Packages (Chapter 13.7) can produce names long enough that an alias is a real improvement:
import flow.parsing.uvm_log_parser as log_parserThat is one dotted name and the alias replaces four segments with two words. Compare it to aliasing json to j, which replaces four characters with one.
The test from Section 5 still applies — log_parser is a name a reader understands without looking anything up, where j is not. A good alias is still descriptive. It is shorter than the original and longer than a letter.
7. Two Aliases, One Module
An alias does not make a copy. It is a name, and nothing about as duplicates
what it points at — which you can check directly:
import statistics as stats
import statistics as s
from statistics import mean as avg
print("A:", stats is s)
print("B:", stats.mean is avg)
print("C:", avg([2, 4]))A: True
B: True
C: 3A — two aliases, one module. is asks whether two names refer to the same
object, and they do. The second import did not load statistics a second time;
it found the already-loaded module and bound another name to it, exactly as
Chapter 13.1 Section 6 described.
B — from statistics import mean as avg binds the function itself, not a
path to it. avg and stats.mean are one object under two names.
That is worth holding onto, because it explains why aliasing is cheap. An alias costs one name binding, never a copy of the module, and never a second load. The argument against a bad alias is entirely about the reader — there is no runtime cost to weigh against it.
8. Predict, Run, Observe
import math as m
from collections import Counter as Bag
# A
print("A:", m.sqrt(16))
# B
print("B:", m.__name__)
# C
print("C:", Bag("aab"))
# D
print("D:", "math" in dir(), "m" in dir())The verified output:
A: 4.0
B: math
C: Counter({'a': 2, 'b': 1})
D: False TrueA — the alias calls the same function.
B — the module still reports its real name.
C — the alias did not rename the type; Counter is what prints.
D — math is not bound and m is. Section 2, as two booleans.
9. Exercises
Exercise 1 — rename both forms. Import statistics under an alias and Counter under an alias, and use each once.
Exercise 2 — the original is gone. Import a module under an alias and then try to use its real name. Record the error and explain it in one sentence using the word "assignment".
Exercise 3 — the necessary case. Write a file with your own parse function that also needs json.loads bound as parse. Make both usable, and say what would happen without the alias.
Exercise 4 — shared or invented. For each, say which and whether you would write it: (a) import numpy as np (b) import json as j (c) import matplotlib.pyplot as plt (d) from pathlib import Path as P (e) import flow.reporting.summary as summary.
Exercise 5 — count the cost. For import statistics as s, count the characters saved per use and estimate how many times a 400-line script might use it. Say whether the trade is worth it and why.
Exercise 6 — the module's own name. Import something under an alias and print its __name__. Explain in one sentence why the alias did not change it.
Exercise 7 — long names. Invent a four-segment dotted module name and alias it well. Say what makes your alias better than a single letter.
Exercise 8 — read it back. Given a file whose imports are import numpy as np, import json as j and from pathlib import Path, say which of the three you would change in review and what you would change it to.
10. Summary
asrenames an import as it arrives, and works on bothimport Xandfrom X import Y.- It renames rather than adding — the original name is not bound at all, because an import is an assignment.
- The alias is local to your file and does not change the module's own
__name__or affect any other file. - The necessary use is disambiguation: two things that want the same name, where Chapter 13.2's collision would otherwise destroy one silently.
- Otherwise the test is one question: is this alias one your reader already knows, or one you invented?
- Shared aliases —
np,pd,plt— are conventions a reader recognises on sight. - Invented aliases are a private code that costs a lookup at every use site.
- Typing is not the cost worth optimising. An alias is written once and read many times.
Path as Pis the canonical example of not worth it — already short, already unmistakable.- Long dotted package names are the real case, and a good alias there is still descriptive.
- An alias is a name, not a copy — two aliases for one module are the same object, and
from X import f as gbinds the function itself.
The next chapter is a tour of what is actually available to import.
Where this fits
Part of the Python curriculum.
