GENERAL PURPOSE · INTERPRETED · ENGINEER EDITION

Python Programming
in a Nutshell

A high-signal reference for Python 3 — language model, data types, OOP, async, performance patterns, standard library, and packaging. From syntax fundamentals to production-grade idioms.

CPython
Reference interpreter in C
GIL
Global Interpreter Lock
PEP 8
Style guide — 4-space indent
3.12+
Current stable release line
SECTION 01

Overview — Python at a Glance

Dynamically typed, garbage-collected, interpreted language with a vast standard library and ecosystem. Philosophy: readability counts, explicit is better than implicit.

LANGUAGE CHARACTERISTICS
Dynamic typing — types resolved at runtime; type(x) always valid
GC — reference counting with cyclic garbage collector
Duck typing — structural compatibility, not nominal
Everything object — ints, functions, classes all are objects
KEY DESIGN PHILOSOPHY (PEP 20)
# import this
"Beautiful is better than ugly."
"Explicit is better than implicit."
"Simple is better than complex."
"Readability counts."
"Errors should never pass silently."
"There should be one obvious way."
PRIMARY USE CASES
Data science / ML  ·  Web backends (Django, FastAPI)  ·  Automation / scripting  ·  Network tools  ·  DevOps / cloud tooling  ·  Desktop GUIs (tkinter, PyQt)
EXECUTION MODEL
Source .py → CPython compiles to .pyc bytecode → executed by PVM (Python Virtual Machine). No AOT compile step; JIT available via PyPy.
VERSION POLICY
Annual October release cadence. 3.12 — GIL opt-out (PEP 703). 3.x only; Python 2 EOL Jan 2020.
SECTION 02

Runtime Architecture

How CPython transforms source code to execution — and the role of the GIL, memory manager, and import system.

Source
.py file → tokenizer → AST (Abstract Syntax Tree) → ast.parse() → inspectable at runtime
Compile
AST → compiler → bytecode (.pyc in __pycache__) → inspectable with dis.dis()
PVM
Python Virtual Machine — stack-based bytecode interpreter. Each thread holds a GIL. CPython switches threads every 5 ms (sys.getswitchinterval)
Memory
pymalloc arena allocator → object-specific allocators (int pool, float pool) → refcount + gc for cycle detection
Import
import → checks sys.modules cache first → searches sys.path → built-ins → frozen → .pth → site-packages
C Ext
C extensions (.so/.pyd) loaded via ctypes / cffi / CPython C API. NumPy, pandas, cryptography etc. bypass PVM for hot loops — GIL released during I/O & C code
THREADING vs MULTIPROCESSING
GIL blocks true CPU parallelism in threads. Use threading for I/O-bound; multiprocessing for CPU-bound (separate GIL per process).
ASYNCIO EVENT LOOP
Single-thread coroutine scheduler. await suspends coroutine, loop runs next ready task. Best for high-concurrency I/O (network, DB).
ALTERNATIVE RUNTIMES
PyPy (JIT, 5–10× faster loops), Cython (C transpile), Numba (LLVM JIT for arrays), GraalPy (GraalVM).
SECTION 03

Core Syntax & Mechanics

Fundamental constructs — control flow, functions, comprehensions, generators, decorators, and type annotations.

FUNCTIONS, CLOSURES & DECORATORS
def greet(name: str, *, loud: bool = False) -> str:
# keyword-only arg after *
msg = f"Hello, {name}"
return msg.upper() if loud else msg
 
def timer(func): # decorator
import time, functools
@functools.wraps(func)
def wrapper(*args, **kwargs):
t = time.perf_counter()
result = func(*args, **kwargs)
print(f"{func.__name__}: {time.perf_counter()-t:.4f}s")
return result
return wrapper
COMPREHENSIONS & GENERATORS
# list / dict / set comprehensions
squares = [x**2 for x in range(10) if x % 2]
inv = {v: k for k, v in d.items()}
uniq = {x.lower() for x in words}
 
# generator — lazy, O(1) memory
def chunks(lst, n):
for i in range(0, len(lst), n):
yield lst[i : i+n]
 
# generator expression
total = sum(x**2 for x in data)
ASYNC / AWAIT (asyncio)
import asyncio, aiohttp
 
async def fetch(session, url):
async with session.get(url) as r:
return await r.text()
 
async def main():
async with aiohttp.ClientSession() as s:
tasks = [fetch(s, u) for u in urls]
results = await asyncio.gather(*tasks)
 
asyncio.run(main()) # entry point
TYPE ANNOTATIONS (PEP 484 / 526)
from typing import TypeVar, Generic
from collections.abc import Callable, Sequence
 
T = TypeVar("T")
 
def first(seq: Sequence[T]) -> T | None:
return seq[0] if seq else None
 
# dataclass with type hints
from dataclasses import dataclass, field
@dataclass
class Site:
name: str
cells: list[str] = field(default_factory=list)
SECTION 04

Data Model & Type Hierarchy

Python's object model — every value is an object with identity, type, and value. Dunder methods wire user classes into the language's core protocols.

Numerics
int float complex decimal.Decimal fractions.Fraction · int is unbounded · bool subclasses int (True==1)
Sequences
list tuple str bytearray array.array · list over-allocates by ~1.125× · tuple faster creation
Mappings
dict collections.OrderedDict defaultdict Counter · dict requires hashable keys · 3.9+ merge: d1 | d2
Sets
set frozenset · ops: | ∪ & ∩ - \ ^ Δ · membership O(1) vs list O(n)
Dunders
__new__ __init__ __del__ __len__ __getitem__ __iter__ __next__ __enter__ __exit__ __str__ __repr__
OOP
MRO (C3 linearisation) · multiple inheritance · super() · @classmethod · @staticmethod · @property · ABC via abc.abstractmethod · slots (__slots__) reduce memory ~40%
SECTION 05

Performance Characteristics

CPython overhead, data structure complexities, and profiling targets. Know these before optimising.

OPERATION / METRIC COMPLEXITY / VALUE WORST CASE NOTE
list.append() O(1) amortised O(n) on resize Over-allocation factor ~1.125×
list.insert(0, x) O(n) O(n) Use deque for O(1) front insert
dict / set lookup O(1) average O(n) hash collision Hash randomisation (PYTHONHASHSEED)
str concatenation loop O(n²) O(n²) Use "".join(parts) — O(n)
CPython function call overhead ~50–200 ns +kwargs/defaults vs C call ~1–5 ns — inline hot paths
List comprehension vs for loop ~1.5–2× faster Same memory if large Bytecode LIST_APPEND vs STORE_FAST
Global vs local variable local ~2× faster LOAD_GLOBAL slower Cache globals in local: x = math.sqrt
PyPy speedup (typical) 4–10× CPython Warm-up overhead Loop-heavy CPU code; not ideal for short scripts
GC pause (cyclic) < 1 ms typical ms range large heaps gc.disable() in tight loops; gc.collect() explicit
PROFILING TOOLS
cProfile — call counts + cumtime  ·  line_profiler — line-level  ·  memory_profiler — RAM per line  ·  timeit — micro-benchmarks  ·  py-spy — sampling profiler (production-safe)
OPTIMISATION CHECKLIST
Profile first → use built-ins (map/filter/sum) → NumPy for array maths → avoid repeated attribute lookup in loops → use __slots__ → switch to Cython/Numba for hot loops
SECTION 06

Development Workflows

Package setup with modern tooling and a production error-handling / logging pattern.

PROJECT SETUP — MODERN TOOLCHAIN
1
Initialise environmentpython -m venv .venv or uv venv. Activate: source .venv/bin/activate. Pin deps with uv pip compile.
2
Define package metadatapyproject.toml (PEP 517/518). Use hatchling, flit, or setuptools as build backend. Add [project.scripts] for CLI entry points.
3
Lint & formatruff (replaces flake8+isort+pyupgrade), black for formatting, mypy or pyright for type checking. Pre-commit hooks enforce on commit.
4
Test & publishpytest with coverage.py. Target ≥ 80% coverage. Publish: python -m buildtwine upload → PyPI.
ERROR HANDLING & LOGGING PATTERN
1
Use specific exceptions — catch the narrowest exception (ValueError, KeyError). Never bare except:. Use except Exception as e + raise ... from e for chaining.
2
Configure logging once at entrylogging.basicConfig(level=INFO) in __main__. Modules use logger = logging.getLogger(__name__). Never print() in library code.
3
Context managers for resourceswith open(...), DB sessions, locks. Implement __enter__/__exit__ or use @contextlib.contextmanager.
4
Structured error responses — in APIs return typed error objects (dataclass / Pydantic model). Use sys.exit(1) on fatal CLI errors after logging the cause.
SECTION 07

Standard Library — Key Modules

The "batteries included" stdlib — reach for these before installing third-party packages.

DATA & ALGORITHMS
collections High-performance container datatypes beyond list/dict
heapq Min-heap priority queue — O(log n) push/pop
bisect Binary search on sorted lists — O(log n)
itertools Lazy iterator combinatorics — memory-efficient pipelines
functools Higher-order functions, memoisation, partial application
I/O, FILES & CONCURRENCY
pathlib OO filesystem paths — prefer over os.path in 3.4+
concurrent.futures High-level thread/process pool with Future objects
asyncio Async I/O event loop — coroutines, tasks, streams
json Built-in JSON encode/decode — use ujson/orjson for perf
csv RFC 4180 CSV read/write — quoting, dialects, delimiters
SYSTEM, PROCESS & INTROSPECTION
sys Runtime environment: argv, path, exc_info, platform
subprocess Spawn, manage, communicate with child processes
inspect Introspect live objects — useful in frameworks & decorators
time / timeit High-res timing — perf_counter for wall-clock benchmarks
POPULAR THIRD-PARTY ECOSYSTEM
NumPy N-dimensional arrays, vectorised ops, C-speed loops
pandas DataFrame/Series — tabular data, groupby, merge, resample
FastAPI Async web framework — auto OpenAPI, Pydantic validation
SQLAlchemy ORM + Core — multiple DB backends, async support (2.0)
Pydantic Data validation via type annotations — powers FastAPI models
SECTION 08

Values Cheatsheet

Quick-reference cards — data type sizes, built-in functions, operator precedence, f-string formats, pytest patterns, and packaging commands.

BUILT-IN FUNCTIONS (MUST-KNOW)
len / range / enumerateiteration
map / filter / ziplazy transforms
sorted / min / max / sumaggregation
any / all / isinstancepredicates
getattr / setattr / hasattrreflection
vars / dir / id / typeintrospection
F-STRING FORMAT SPECIFIERS
f"{3.14159:.2f}" # "3.14"
f"{1000000:,}" # "1,000,000"
f"{0.856:.1%}" # "85.6%"
f"{255:#010x}" # "0x000000ff"
f"{'hi':^20}" # " hi "
f"{val!r}" # repr(val)
f"{val=}" # "val=42" (debug)
DATA TYPE MEMORY SIZES (CPython 3.12)
int (small)28 bytes
float24 bytes
str (empty)49 bytes + 1–4/char
list (empty)56 bytes + 8/item
dict (empty)184 bytes
set (empty)216 bytes
OPERATOR PRECEDENCE (HIGH→LOW)
() [] {}grouping / subscript
**exponentiation (right-assoc)
* / // % @multiplicative
+ -additive
<< >> & ^ |bitwise
not and orboolean
PYTEST PATTERNS
import pytest
 
def test_basic():
assert add(1, 2) == 3
 
@pytest.mark.parametrize("a,b,expected", [
(1, 2, 3), (0, 0, 0), (-1, 1, 0),
])
def test_add(a, b, expected):
assert add(a, b) == expected
 
def test_raises():
with pytest.raises(ValueError, match="negative"):
sqrt(-1)
PACKAGING & ENV COMMANDS
# virtualenv
python -m venv .venv && source .venv/bin/activate
 
# uv (fast Rust-based tool)
uv venv && uv pip install -r requirements.txt
uv pip compile requirements.in -o requirements.txt
 
# build & publish
python -m build # creates dist/
twine upload dist/* # push to PyPI
 
# freeze installed
pip freeze > requirements.txt