Standard Library Tour
|
This section documents the current Python release line as published at the official Python documentation, which is the reference these pages are written and verified against. No specific patch version is pinned. This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
Python ships "batteries included": the modules on this page cover filesystem access, structured data, text patterns, math, and command-line tooling without installing anything. The tutorial’s Brief Tour of the Standard Library and Brief Tour, Part II introduce many of these modules in context; the full, authoritative catalogue of every module is the Python Standard Library reference.
Filesystem and OS
os and sys
os exposes the operating system’s process and filesystem interface; sys exposes interpreter state,
including the command-line arguments and the process exit code:
import os
import sys
print(os.getcwd()) # current working directory
print(os.environ.get("HOME", "")) # environment variable, with a default
if len(sys.argv) < 2:
print("usage: script.py <name>", file=sys.stderr)
sys.exit(1) # nonzero exit code signals failure to the calling shell
name = sys.argv[1] # sys.argv[0] is the script name itself
print(f"hello, {name}")
sys.exit(0) # 0 signals success
Full references: the os module and
the sys module.
pathlib
pathlib.Path is the modern, object-oriented alternative to building paths from os.path strings. Opening,
reading, writing, and joining paths with Path — plus the enter/exit protocol behind with — are covered in depth on Files and Context Managers; this page only adds the piece that
belongs alongside glob below, directory-tree pattern matching:
from pathlib import Path
for csv_path in Path("data").glob("*.csv"): # non-recursive, like glob.glob()
print(csv_path)
for csv_path in Path("data").rglob("*.csv"): # recursive, like glob.glob(..., recursive=True)
print(csv_path)
Reference: the pathlib module.
glob
glob matches filesystem paths against shell-style wildcards (*, ?, […]) and predates pathlib:
import glob
for path in glob.glob("data/*.csv"):
print(path)
for path in glob.glob("data/**/*.csv", recursive=True): # ** descends into subdirectories
print(path)
Reference: the glob module.
shutil
shutil provides the higher-level file operations os does not: copying, moving, and recursively deleting
whole trees:
import shutil
shutil.copy("notes.txt", "backup/notes.txt") # copy one file (metadata included with copy2)
shutil.copytree("data", "data_backup") # recursively copy a directory tree
shutil.rmtree("data_backup") # recursively delete a directory tree
Reference: the shutil module.
Data: Dates, JSON, Patterns, and Collections
datetime
from datetime import datetime, timedelta
now = datetime.now()
tomorrow = now + timedelta(days=1)
print(now.strftime("%Y-%m-%d")) # formatted string, e.g. '2026-09-05'
parsed = datetime.strptime("2026-01-15", "%Y-%m-%d") # parse a string back into a datetime
print(parsed.year, parsed.month, parsed.day)
Reference: the datetime module.
json
json.dumps() serializes Python objects (dicts, lists, strings, numbers, booleans, None) to a JSON string;
json.loads() parses one back:
import json
data = {"name": "Ada", "languages": ["python", "ocaml"]}
text = json.dumps(data, indent=2) # dict -> JSON string
print(text)
restored = json.loads(text) # JSON string -> dict
assert restored == data
Reference: the json module.
re
re implements Perl-style regular expressions: search() finds the first match anywhere in the string,
findall() returns every match, and sub() replaces matches. Quantifiers such as {3} (exactly three
repeats) or \{2,4\} (two to four) and groups written with (…) are the essentials for most patterns:
import re
text = "Call 555-1234 or 555-5678"
pattern = r"\d{3}-\d{4}"
print(re.findall(pattern, text)) # ['555-1234', '555-5678']
match = re.search(r"(\d{3})-(\d{4})", text)
if match:
print(match.group(1), match.group(2)) # '555' '1234'
print(re.sub(pattern, "REDACTED", text)) # 'Call REDACTED or REDACTED'
Reference: the re module.
collections
Beyond the built-in list/dict/set/tuple covered on Collections, the
collections module adds specialized container types. Counter tallies items, defaultdict supplies a
default value instead of raising KeyError on a missing key, and namedtuple gives tuple elements names:
from collections import Counter, defaultdict, namedtuple
words = ["a", "b", "a", "c", "b", "a"]
counts = Counter(words)
print(counts) # Counter({'a': 3, 'b': 2, 'c': 1})
print(counts.most_common(1)) # [('a', 3)]
groups = defaultdict(list)
for word in words:
groups[word[0]].append(word) # no KeyError the first time a key is seen
print(dict(groups))
Point = namedtuple("Point", ["x", "y"])
p = Point(1, 2)
print(p.x, p.y) # 1 2 -- plus regular tuple behavior: p[0], unpacking, etc.
Reference: the collections module.
itertools
itertools builds lazy iterators for combinatorics and infinite/composite sequences — see
Iterators, Generators, and Comprehensions for the iterator protocol these are built on:
import itertools
for a, b in itertools.product([1, 2], ["x", "y"]):
print(a, b) # (1,x) (1,y) (2,x) (2,y)
print(list(itertools.chain([1, 2], [3, 4]))) # [1, 2, 3, 4]
print(list(itertools.islice(itertools.count(10), 3))) # [10, 11, 12] -- lazy infinite counter, sliced
Reference: the itertools module.
functools
reduce() folds an iterable down to a single value, lru_cache memoizes a function’s results, and
partial() freezes some of a function’s arguments ahead of time:
from functools import reduce, lru_cache, partial
total = reduce(lambda acc, x: acc + x, [1, 2, 3, 4], 0) # 10 (sum() is clearer for this specific case)
@lru_cache(maxsize=None)
def fib(n):
return n if n < 2 else fib(n - 1) + fib(n - 2)
print(fib(30)) # cached: repeat calls with the same n cost O(1) after the first
add_ten = partial(lambda x, y: x + y, 10) # first argument frozen to 10
print(add_ten(5)) # 15
Reference: the functools module.
Math and Random
math
import math
print(math.sqrt(2)) # 1.4142135623730951
print(math.floor(3.7), math.ceil(3.2)) # 3 4
print(math.gcd(12, 18)) # 6
print(math.pi) # 3.141592653589793
Reference: the math module.
random
import random
random.seed(42) # fixes the sequence -- useful for reproducible tests
print(random.randint(1, 6)) # random int in [1, 6], both ends inclusive
print(random.choice(["a", "b", "c"])) # one random element
sample = list(range(10))
random.shuffle(sample) # shuffles in place, returns None
print(random.sample(range(100), 5)) # 5 unique values, no repeats
Reference: the random module.
statistics
import statistics
data = [2, 4, 4, 4, 5, 5, 7, 9]
print(statistics.mean(data)) # 5
print(statistics.median(data)) # 4.5
print(statistics.stdev(data)) # sample standard deviation
Reference: the statistics module.
CLI and Observability
argparse
argparse replaces hand-parsing sys.argv: declare positional and optional arguments once, and it builds
the parsing, type conversion, defaults, and --help text for free:
import argparse
parser = argparse.ArgumentParser(description="Greet someone")
parser.add_argument("name") # positional, required
parser.add_argument("--shout", action="store_true") # optional boolean flag
parser.add_argument("--times", type=int, default=1) # optional value, converted to int
args = parser.parse_args() # reads sys.argv by default
greeting = f"hello, {args.name}"
if args.shout:
greeting = greeting.upper()
for _ in range(args.times):
print(greeting)
A script built this way is typically installed and run as a console-script entry point inside its own virtual environment — see Virtual Environments and Packaging for packaging a CLI tool so it can be installed and invoked by name.
Reference: the argparse module.
logging
logging is the leveled, configurable alternative to scattering and later deleting print() calls. Levels
run DEBUG < INFO < WARNING < ERROR < CRITICAL; only messages at or above the configured level are emitted:
import logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger(__name__)
logger.debug("won't show at INFO level")
logger.info("starting job")
logger.warning("disk space low")
try:
1 / 0
except ZeroDivisionError:
logger.error("division failed", exc_info=True) # exc_info=True attaches the traceback
Because the level is set in one place (basicConfig, or a config file), a whole codebase’s verbosity can be
turned up or down without touching a single call site — something print()-debugging cannot offer.
Reference: the logging module.
See Also
-
Files and Context Managers —
pathlib.Pathfor path joining, reading, and writing, and thewith/context-manager protocol these examples build on. -
Virtual Environments and Packaging — installing packages and packaging an
argparse-based script as a runnable console command.