Comprehensive reference for python stdlib reference covering essential concepts, practical examples, and production best practices.
Python Stdlib Reference is a curated guide to the core libraries included with Python, focused on the commands, modules, and idioms engineers use daily—especially when debugging, building tools, or deploying services. It details the exact behavior of standard library components with minimal abstraction, emphasizing what works, what breaks silently, and how to recognize and fix common pitfalls.
pathlib.Pathfrom pathlib import Path
# Read a file
data = (Path("data") / "config.json").read_text(encoding="utf-8")
# Write a file with directory creation
(Path("logs") / "app.log").write_text("Starting service...", encoding="utf-8")
# Iterate over files with glob patterns
for file_path in Path("src").glob("*.py"):
print(file_path.name)
Path is the preferred interface over os.path. It supports / for path joining and with context manager.Path.read_text() and Path.write_text() default to encoding="utf-8"—but fail silently if encoding mismatch occurs.Path.glob("*.py") returns an iterator, not a list. Use list(Path.glob(...)) for eager evaluation.os.stat()import os
stat_info = os.stat("example.txt")
print(stat_info.st_mtime) # last modification time (float seconds since epoch)
print(stat_info.st_size) # file size in bytes
print(stat_info.st_mode) # file mode (e.g., 0o100644 for regular file)
os.stat() returns a os.stat_result tuple-like object with named fields.os.stat() on a non-existent file raises FileNotFoundError, but os.path.exists() does not—it returns False for missing files, but os.stat() fails with FileNotFoundError.os.walk()for root, dirs, files in os.walk("project"):
for file in files:
full_path = os.path.join(root, file)
if file.endswith(".py"):
print(f"Python file: {full_path}")
os.walk() yields (root, dirs, files) tuples. dirs is mutable: modifying it filters subdirectories.dirs during traversal is a common source of missed directories.reimport re
# Compile pattern once for performance
pattern = re.compile(r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z]{2,}\b", flags=re.IGNORECASE)
# Search with full match details
match = pattern.search("Contact: [email protected] for help")
if match:
print(match.group()) # '[email protected]'
print(match.start(), match.end()) # 10, 34
print(match.groups()) # ('[email protected]',)
# Substitution with function
def camel_to_snake(name):
return re.sub(r"(?<!^)(?=[A-Z])", "_", name).lower()
print(camel_to_snake("CamelCaseString")) # 'camel_case_string'
re.compile() returns a Pattern object. Use pattern.search() or pattern.match()—match() requires match from start, search() finds anywhere.re.sub() supports repl as string or function. When using a function, it receives the Match object.re.split() returns a list, but re.finditer() returns an iterator of Match objects.str.format() and f-stringsname = "Alice"
age = 30
# Using str.format()
template = "Hello, {name}. You are {age} years old."
print(template.format(name=name, age=age))
# Using f-strings (preferred)
print(f"Hello, {name}. You are {age} years old.")
# f-string with expression and formatting
print(f"Next year: {age + 1} ({name.upper()})")
f"{expr}" evaluate expr each time, not just once.f"{value:width.precision}" supports formatting: f"{pi:.4f}" → '3.1416'.f"{value:0>8}" pads to width 8 with zeros, right-aligned.jsonimport json
# Parse JSON from string
data = json.loads('{"name": "Alice", "age": 30}')
print(data["name"]) # "Alice"
# Serialize to string
json_str = json.dumps(data, indent=2, sort_keys=True)
# Read from file
with open("config.json", "r", encoding="utf-8") as f:
config = json.load(f)
# Write to file
with open("output.json", "w", encoding="utf-8") as f:
json.dump(data, f, indent=2)
json.load() and json.dump() expect file-like objects (with read() and write()).json.load() silently fails on malformed JSON, returning None or default value.json.dumps() does not preserve datetime objects unless default is provided.import datetime
def serialize_datetime(obj):
if isinstance(obj, datetime.datetime):
return obj.isoformat()
raise TypeError(f"Object of type {type(obj)} not serializable")
json.dumps(data, default=serialize_datetime)
import pickle
# Serialize object
with open("data.pkl", "wb") as f:
pickle.dump(data, f)
# Deserialize object
with open("data.pkl", "rb") as f:
loaded_data = pickle.load(f)
# Bulk operations
with open("data.pkl", "rb") as f:
objects = pickle.load(f)
more_objects = pickle.load(f) # reads next object from same file
pickle.dump() writes a single object to a file, pickle.load() reads one from a file.pickle.dump() calls write multiple pickled objects to the same file—pickle.load() reads them sequentially.pickle.HIGHEST_PROTOCOL is the default, but pickle.PicklingError can occur during serialization.datetime and timefrom datetime import datetime, timedelta, timezone
now = datetime.now()
utc_now = datetime.now(timezone.utc)
# Format
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
# Parse
parsed = datetime.strptime("2023-10-05 14:30:00", "%Y-%m-%d %H:%M:%S")
# Time arithmetic
future = now + timedelta(days=7, hours=3)
print(future)
# Time zone handling
utc = timezone.utc
eastern = timezone(timedelta(hours=-5))
dt = datetime(2023, 10, 5, 14, 30, tzinfo=utc)
eastern_time = dt.astimezone(eastern)
datetime.now() returns datetime object with tzinfo=None. Use datetime.now(timezone.utc) for UTC-aware times.timedelta supports days, seconds, microseconds, milliseconds, minutes, hours, weeks.datetime.strftime() and strptime() use the same format codes, but strftime() uses %Y for 4-digit year, %y for 2-digit.datetime.astimezone() creates a new datetime object; replace(tzinfo=...) does not adjust the time.time moduleimport time
start = time.time()
# ... work ...
elapsed = time.time() - start
# Sleep with fractional seconds
time.sleep(0.123) # 123 milliseconds
# Get current time in seconds since epoch
epoch = time.time()
# Get time as struct
now_struct = time.localtime()
print(now_struct.tm_year) # 2023
print(time.strftime("%H:%M:%S", now_struct))
# High-resolution timer
start_ns = time.perf_counter()
# ... work ...
elapsed_ns = time.perf_counter() - start_ns
time.time() returns float seconds since epoch (UTC).time.sleep() is blocking, and does not return immediately.time.perf_counter() is high-resolution, monotonically increasing, and suitable for benchmarking.subprocess for Running External Commandsimport subprocess
# Run command and capture output
result = subprocess.run(
["git", "status", "--porcelain"],
capture_output=True,
text=True,
check=True,
)
print(result.stdout) # list of changed files
# Handle non-zero exit
try:
subprocess.run(
["python", "main.py"],
check=True,
timeout=30,
)
except subprocess.CalledProcessError as e:
print(f"Command failed: {e.cmd}")
print(f"Return code: {e.returncode}")
print(f"Output: {e.output}")
print(f"Stderr: {e.stderr}")
# Pipe input
result = subprocess.run(
["grep", "error"],
input="Error: File not found\nWarning: Low disk space\nError: Timeout",
text=True,
capture_output=True,
)
subprocess.run() is the preferred interface.capture_output=True sets stdout=PIPE, stderr=PIPE.check=True raises CalledProcessError on non-zero exit.timeout=30 raises TimeoutExpired after 30 seconds.input argument provides stdin; text=True enables text mode (str input/output).argparse for Command-Line Interfaceimport argparse
parser = argparse.ArgumentParser(description="Process data files.")
parser.add_argument("input", help="Input file path")
parser.add_argument("-o", "--output", help="Output file path", default="output.json")
parser.add_argument("-v", "--verbose", action="store_true", help="Enable verbose output")
parser.add_argument("--limit", type=int, default=100, help="Maximum number of records to process")
args = parser.parse_args()
if args.verbose:
print(f"Processing {args.input} -> {args.output}")
for i in range(args.limit):
# process records
pass
action="store_true" creates a boolean flag.type=int parses argument as integer; type=str is default.parser.parse_args() returns a Namespace object.parser.parse_args() reads sys.argv by default; pass argv to override.logging Moduleimport logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s | %(name)s | %(levelname)s | %(message)s",
handlers=[logging.FileHandler("app.log"), logging.StreamHandler()],
)
logger = logging.getLogger("main")
logger.info("Starting application")
logger.warning("Low disk space")
logger.error("Failed to connect to database")
try:
result = 10 / 0
except Exception as e:
logger.exception("An error occurred")
logging.basicConfig() sets up root logger.logger.exception() logs the exception stack trace.logger.info() logs at level INFO, but logger.debug() does nothing unless level=logging.DEBUG.logging.StreamHandler() writes to sys.stdout or sys.stderr.traceback for Exception Detailsimport traceback
try:
1 / 0
except Exception as e:
print(traceback.format_exc())
traceback.format_exc() returns a string with full stack trace.traceback.print_exc() prints directly to sys.stderr.collections Modulefrom collections import Counter, defaultdict, deque
# Count items
items = ["apple", "banana", "apple", "cherry", "banana", "apple"]
counts = Counter(items)
print(counts["apple"]) # 3
# Default dictionary
word_lengths = defaultdict(int)
for word in ["hello", "world", "hello"]:
word_lengths[word] += len(word)
# Deque for efficient appends and pops from both ends
queue = deque(maxlen=10)
queue.append("first")
queue.appendleft("last")
queue.append("new")
print(queue.popleft()) # "last"
Counter supports most_common(n) and update(iterable).defaultdict takes a factory function: defaultdict(list) creates a list for missing keys.deque supports append(), appendleft(), pop(), popleft(), extend(), extendleft(), and maxlen.itertools for Efficient Iterationimport itertools
# Infinite iterators
cycle = itertools.cycle(["a", "b", "c"])
for i, item in enumerate(itertools.islice(cycle, 10)):
print(f"{i}: {item}")
# Combinatorics
for combo in itertools.combinations([1, 2, 3], 2):
print(combo) # (1, 2), (1, 3), (2, 3)
# Grouping
data = [("A", 1), ("B", 2), ("A", 3)]
sorted_data = sorted(data, key=lambda x: x[0])
for key, group in itertools.groupby(sorted_data, key=lambda x: x[0]):
print(f"Group {key}: {list(group)}")
itertools.islice() returns an iterator; itertools.chain() concatenates iterables.itertools.groupby() requires input to be sorted by the grouping key.itertools.product() creates Cartesian product of iterables.zip and itertools.zip_longestnames = ["Alice", "Bob"]
ages = [30, 25]
# Regular zip
for name, age in zip(names, ages):
print(f"{name} is {age} years old")
# Zip with fill value
from itertools import zip_longest
for name, age in zip_longest(names, ages, fillvalue="Unknown"):
print(f"{name} is {age} years old")
zip() stops at the shortest input.zip_longest() fills with fillvalue for missing values.def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
# Use generator
fib = fibonacci()
first_ten = [next(fib) for _ in range(10)]
print(first_ten) # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
yield suspends function and returns a generator object.next(generator) advances one step.This page was rewritten on 10 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.
We use cookies for analytics (Google Analytics) and advertising (Google AdSense) to improve your experience and support free content. Privacy Policy