Python snippets¶
Common patterns I copy-paste constantly.
Virtual environments and pip¶
Create and activate a venv, install dependencies:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Capture the exact installed versions to a lock file:
pip freeze > requirements.txt
Install a package in editable mode (useful during local development):
pip install -e .
List and dict comprehensions¶
Filter and transform in one expression:
# squares of even numbers
squares = [x**2 for x in range(20) if x % 2 == 0]
# invert a dict
inv = {v: k for k, v in original.items()}
# flatten a list of lists
flat = [item for row in matrix for item in row]
pathlib — modern filesystem paths¶
pathlib.Path objects compose cleanly and carry their own operations:
from pathlib import Path
base = Path("/var/data")
report = base / "reports" / "2024-q4.csv"
report.parent.mkdir(parents=True, exist_ok=True)
report.write_text("date,value\n2024-10-01,42\n")
for f in base.glob("**/*.csv"):
print(f.stem, f.stat().st_size)
argparse — CLI arguments¶
A minimal script that accepts a positional argument and a flag:
import argparse
def parse_args():
p = argparse.ArgumentParser(description="Process a data file.")
p.add_argument("input", type=Path, help="Input CSV path")
p.add_argument("-o", "--output", type=Path, default=Path("out.csv"))
p.add_argument("-v", "--verbose", action="store_true")
return p.parse_args()
args = parse_args()
if args.verbose:
print(f"Reading {args.input}")
dataclasses¶
Clean data containers without boilerplate __init__:
from dataclasses import dataclass, field
from typing import List
@dataclass
class Config:
host: str
port: int = 8080
tags: List[str] = field(default_factory=list)
cfg = Config(host="localhost", tags=["web", "api"])
print(cfg) # Config(host='localhost', port=8080, tags=['web', 'api'])
field(default_factory=list) avoids the mutable-default-argument trap.
with — context managers¶
Open files safely (closed even on exception):
with open("data.txt") as fh:
content = fh.read()
Write multiple files atomically with nested with:
with open("a.txt", "w") as a, open("b.txt", "w") as b:
a.write("hello\n")
b.write("world\n")
Roll your own context manager:
from contextlib import contextmanager
@contextmanager
def timer(label: str):
import time
start = time.perf_counter()
yield
print(f"{label}: {time.perf_counter() - start:.3f}s")
with timer("sort"):
sorted(range(10_000_000))
requests — HTTP GET¶
Fetch JSON from an API with a timeout and error check:
import requests
resp = requests.get(
"https://api.example.com/items",
headers={"Authorization": "Bearer TOKEN"},
timeout=10,
)
resp.raise_for_status() # raises HTTPError on 4xx/5xx
data = resp.json()
json — load and dump round-trip¶
import json
from pathlib import Path
raw = Path("config.json").read_text()
cfg = json.loads(raw)
cfg["version"] = 2
Path("config.json").write_text(json.dumps(cfg, indent=2))
indent=2 produces human-readable output; omit it for compact serialization.
See also: Bash patterns for wrapping Python scripts in shell entry-points.