Python is a high-level, interpreted programming language created by Guido van Rossum in 1991, emphasizing code readability through significant whitespace and a philosophy of "there should be one obvious way to do it." It's widely used across web development, data science, automation, machine learning, and systems programming, powered by a vast ecosystem of packages and an active global community. Python 3.14 (released October 2025) introduced deferred annotation evaluation, t-strings, and officially supported free-threading β marking one of the most significant runtime shifts in Python's history. The key to mastering Python isn't just knowing syntax β it's understanding when to use list comprehensions over loops, how duck typing works, and why context managers matter for resource safety.
26 tables, 362 concepts. Select a concept node to jump to its table row.
Table 1: Data Types
Python's built-in types are the foundation every program builds on. Knowing which are mutable, which are hashable, and how each behaves in memory keeps you out of the most common Python traps β like assuming bool is not an int, or that two distinct lists with equal contents are the same object.
| Type | Example | Description |
|---|---|---|
x = 42 | Arbitrary-precision integers β no overflow limit unlike most languages. | |
y = 3.14 | β’ Double-precision floating-point (64-bit IEEE 754) β’ beware rounding errors with exact comparisons. | |
s = "hello" | β’ Immutable sequence of Unicode characters β’ supports f-strings, slicing, and a rich method surface. | |
flag = True | β’ Subclass of int β True is 1 and False is 0β’ this surprises most newcomers | |
arr = [1, 2, 3] | Mutable ordered sequence β the most versatile and commonly used collection type. | |
d = {"key": "val"} | β’ Mutable mapping of unique keys to values β’ insertion-ordered since Python 3.7. | |
t = (1, 2, 3) | β’ Immutable ordered sequence β’ hashable when elements are hashable β usable as dict keys. | |
s = {1, 2, 3} | β’ Mutable unordered collection of unique hashable elements β’ O(1) membership test. | |
fs = frozenset([1, 2]) | β’ Immutable version of setβ’ hashable β can be a dict key or set element. | |
x = None | β’ Singleton representing absence of value β’ distinct from empty collections or zero | |
b = b"data" | β’ Immutable sequence of byte values (0β255) β’ for binary data and network protocols | |
ba = bytearray(b"x") | Mutable version of bytes β for in-place modification of binary data. | |
r = range(10) | Immutable sequence representing an arithmetic progression β memory-efficient for iteration. | |
z = 1 + 2j | β’ Numbers with real and imaginary parts β’ j suffix denotes the imaginary unit |
Table 2: Operators
Every Python operator looks familiar from other languages, but most carry one or two Python-specific subtleties β true vs floor division, modulo whose sign follows the divisor, right-associative **, short-circuit and/or that return operands instead of booleans. The newer additions (:= walrus, | for dicts) reflect Python's continuing language design.
| Operator | Example | Description |
|---|---|---|
x + y, x - y, x * y | Addition, subtraction, multiplication β work on numbers and some sequences (like str, list). | |
x / y | Always returns float even for integer operands β true division since Python 3. | |
x // y | β’ Rounds down to nearest integer β’ result type follows operands ( int//int β int). | |
x % y | Remainder β sign matches divisor, unlike C/Java where it matches the dividend. | |
x ** y | β’ Raises x to power yβ’ right-associative and supports fractional/negative exponents | |
x == y, x < y, x >= y | Equality and ordering β chainable like 1 < x < 10 (evaluates each pair once). | |
x is y | Tests if objects are the same instance in memory β not value equality. | |
x in y | β’ Checks if x exists in container yβ’ O(1) for sets and dicts | |
x and y | Returns first falsy value or last value if all truthy β short-circuits. | |
x or y | Returns first truthy value or last value if all falsy β short-circuits. | |
not x | Boolean negation β returns True if x is falsy. | |
x & y | β’ Bitwise AND of integers β’ also set intersection for sets | |
x | y | β’ Bitwise OR of integers β’ also set union for sets | |
x ^ y | β’ Bitwise exclusive OR β’ also symmetric difference for sets | |
~x | β’ One's complement β inverts all bits β’ result is -(x+1). | |
x << n | β’ Shifts bits left by nβ’ equivalent to multiplying by 2**n. | |
x >> n | β’ Shifts bits right by nβ’ equivalent to floor-dividing by 2**n. | |
(x := 5) | Assigns and returns value in a single expression β useful in while and comprehensions (3.8+). | |
d1 | d2 | β’ Merges two dicts into a new dict β’ |β’ = updates in-place (Python 3.9+). |
Table 3: String Operations
Strings are immutable Unicode sequences with a rich method surface for searching, splitting, joining, and formatting. Modern code reaches for f-strings for interpolation, str.join for performant concatenation, and the removeprefix/removesuffix pair for safe edge trimming β and always passes encoding="utf-8" to open() to avoid locale-dependent surprises.
| Method | Example | Description |
|---|---|---|
f"{x} + {y} = {x+y}" | β’ Fastest and most readable formatting β’ supports expressions, format specs, and nested quotes since 3.12. | |
"{} {}".format(a, b) | String formatting with positional/keyword arguments β more verbose than f-strings. | |
s.split(",") | β’ Splits into list by delimiter β’ default splits on any whitespace and removes empty strings | |
",".join(items) | Concatenates an iterable into a single string β preferred over += in loops for performance. | |
s.strip() | β’ Removes leading and trailing whitespace β’ lstrip()/rstrip() for one side only | |
s.removeprefix("pre") | β’ Removes exact prefix or suffix if present β’ returns unchanged string otherwise (Python 3.9+). | |
s.replace("old", "new") | β’ Returns copy with all occurrences replaced β’ optional count parameter to limit replacements | |
s.upper() | β’ Case conversion β’ casefold() for aggressive case-insensitive comparisons across locales | |
s.startswith("pre") | Checks prefix/suffix β accepts a tuple of multiple options. | |
s.find("sub") | β’ Finds substring position β’ find() returns -1 if not found, index() raises ValueError. | |
s.count("x") | Returns the number of non-overlapping occurrences of a substring. | |
s.partition(":") | β’ Splits into 3-tuple (before, sep, after)β’ always returns 3 parts even if separator not found | |
s.isdigit() | β’ Character-type checks β’ many variants: isalnum(), isspace(), islower(), isupper(). | |
s.encode("utf-8") | β’ Converts str β bytes via encoding β’ bytes.decode("utf-8") reverses it | |
s.center(20, "*") | β’ Pads string to a given width with fill character β’ useful for formatting output | |
"42".zfill(5) | Pads with leading zeros to specified width β "00042". | |
s.title() | β’ title() capitalizes each wordβ’ capitalize() only the first character of the whole string | |
s.translate(str.maketrans("abc","ABC")) | Replaces characters per a mapping table β efficient for multi-character substitution. | |
t"Hello {name}" | Template strings producing a Template object for custom processing and safe interpolation (Python 3.14+). | |
"%s %d" % (s, n) | C-style formatting β replaced by f-strings but still seen in legacy code. |
Table 4: Slicing and Indexing
Slice syntax [start:stop:step] is the unified way to index Python sequences β zero-based, half-open, and quietly forgiving of out-of-range indices. The same three components handle reversal ([::-1]), shallow copies ([:]), every-other-element selection ([::2]), and reverse walks, making slicing one of the highest-leverage pieces of syntax to master.
| Pattern | Example | Description |
|---|---|---|
s[0], s[2] | Zero-based indexing from start β first element is [0]. | |
s[-1], s[-2] | Indexes from end β -1 is last element, -2 is second-to-last. | |
s[1:4] | Elements from index 1 up to (but not including) 4 β half-open interval. | |
s[:3] | From beginning to index 3 β equivalent to s[0:3]. | |
s[2:] | From index 2 to end β includes the last element. | |
s[:] | Creates a shallow copy of the entire sequence. | |
s[::2] | Every 2nd element β third parameter is step size. | |
s[::-1] | Reverses sequence β negative step iterates backward. | |
s[4:1:-1] | From index 4 down to (but not including) 1. |
Table 5: Control Flow
Python's control-flow keywords stay deliberately small: if/elif/else driven by truthiness, two loop forms with the unusual else clause, and (since 3.10) structural match with rich pattern types. The match statement goes far beyond a switch β it destructures sequences, mappings, class instances, and supports OR patterns, guards, and wildcard captures in one readable block.
| Statement | Example | Description |
|---|---|---|
if x > 0: print("pos") | Conditional execution β tests truthiness of expression. | |
elif x == 0: print("zero") | Chain multiple conditions β only the first true branch executes. | |
else: print("neg") | Executes when all preceding conditions are false. | |
x if cond else y | Inline conditional β returns x if cond is true, else y. | |
for i in range(5): print(i) | Iterates over any iterable object β most common loop type. | |
while x > 0: x -= 1 | β’ Repeats while condition is truthy β’ check happens before each iteration | |
break | Exits innermost enclosing loop immediately. | |
continue | Skips to the next iteration of the innermost loop. | |
for i in items: passelse: print("done") | Executes if loop completes without break β useful for search patterns. | |
pass | Null operation β syntactic placeholder where a statement is required. | |
match x: case 1: print("one") | Structural pattern matching β compares against literal values (Python 3.10+). | |
case 1 | 2 | 3: | β’ Matches multiple values in one case arm using |β’ (Python 3.10+). | |
case Point(x=x, y=y): | Destructures class instances by attribute names into local variables (Python 3.10+). | |
case [first, *rest]: | Matches and unpacks sequences β *rest captures remaining items (Python 3.10+). | |
case {"action": a}: | Matches dicts by key presence β **rest captures remaining keys (Python 3.10+). | |
case x if x > 0: | Adds a condition to any pattern β branch only executes if guard is true (Python 3.10+). | |
case _: | Catch-all pattern that matches anything β like default in other languages (Python 3.10+). |
Table 6: Functions
Functions are first-class values in Python β they can be passed, returned, default-parameterized, decorated, and unpacked from iterables. Two non-obvious facts dominate the rough edges: default arguments are evaluated once at definition time (the source of the mutable-default trap), and the / and * separators in signatures enforce positional-only and keyword-only calling conventions explicitly.
| Technique | Example | Description |
|---|---|---|
def func(a, b): return a + b | β’ Creates a reusable code block β’ return without value returns None. | |
def f(x, y=10): | β’ Parameters with default values β must come after required params β’ evaluated once at definition. | |
f(x=1, y=2) | Named parameters β allows any order at call site and improves call-site clarity. | |
def f(a, b, /, c): | Parameters before / cannot be passed by keyword β enforces positional calling (Python 3.8+). | |
def f(a, *, b): | Parameters after bare * must be passed by keyword β prevents accidental positional misuse. | |
def f(*args): | Variable positional arguments β collected as a tuple. | |
def f(**kwargs): | Variable keyword arguments β collected as a dict. | |
lambda x: x * 2 | Anonymous function β single expression only, no statements. | |
"""Description.""" | First string in function body β accessible via __doc__ and used by help(). | |
def f(x: int) -> int: | Optional annotations β not enforced at runtime but used by type checkers. | |
f(*args, **kwargs) | Expands sequences and mappings into function arguments at call time. |
Table 7: Comprehensions and Generators
List, dict, and set comprehensions build a collection from an iterable in one expression β typically faster than the equivalent for/append loop and easier to read. Generator expressions and yield-based functions use almost the same syntax but produce lazy iterators, which is what lets Python stream gigabytes without loading them into memory.
| Technique | Example | Description |
|---|---|---|
[x**2 for x in range(10)] | Creates a list from an iterable β faster and cleaner than for-loop append. | |
[x for x in nums if x > 0] | Filters elements β condition acts as an inline filter on the iterable. | |
[x+y for x in a for y in b] | Multiple for clauses β left-to-right nesting order (outer loop first). | |
{k: v**2 for k, v in d.items()} | Creates a dict from an iterable β key-value pairs with unique keys (later values win). | |
{x**2 for x in nums} | Creates a set β automatically deduplicates results. | |
(x**2 for x in range(10)) | β’ Lazy evaluation β memory-efficient for large sequences β’ not stored in memory | |
def gen(): yield x | Function with yield β pauses and resumes execution on each next() call. | |
yield from iterable | Delegates to a subiterator β simplifies nested generators (Python 3.3+). |
Table 8: Classes and OOP
Python's class model favors flexibility over enforcement β no private attributes, no compile-time type checks, no formal interfaces. What you do get is a predictable MRO via C3 linearization, descriptor-driven property access, real multiple inheritance, and abc.ABC for defining enforced interfaces without metaclass boilerplate.
| Concept | Example | Description |
|---|---|---|
class Dog: pass | Creates a new type β naming convention is PascalCase. | |
def __init__(self, name): | Constructor β initializes instance when object is created. | |
self.name = name | Per-object data β defined in __init__ or other methods via self. | |
class Dog: species = "Canis" | Shared across all instances β defined at class level. | |
def bark(self): | Functions bound to instance β first param is self by convention. | |
class Puppy(Dog): | Derives from parent class β inherits attributes and methods. | |
super().__init__(name) | Calls parent class method β handles multiple inheritance via MRO correctly. | |
def age(self): | Getter method β accessed like an attribute but computed dynamically. | |
def age(self, val): | Setter method β allows validation and side effects on attribute assignment. | |
def factory(cls): | Method receives class, not instance β for alternative constructors. | |
def util(): | Regular function in class namespace β no implicit first parameter. | |
class C(A, B): | Inherits from multiple classes β uses C3 MRO to resolve method order. | |
from abc import ABC, abstractmethodclass Shape(ABC): def area(self): ... | Enforces interface β subclasses cannot be instantiated until all abstract methods are implemented. | |
def __repr__(self): | String representations β __repr__ for debugging, __str__ for users. | |
__slots__ = ('x', 'y') | Declares fixed attributes β reduces memory and blocks __dict__ creation. | |
def __new__(cls): | β’ Static method that creates the instance before __init__β’ needed for immutable subclasses | |
def __init_subclass__(cls): | Hook called when a class is subclassed β lightweight alternative to metaclasses (Python 3.6+). |
Table 9: Magic Methods (Dunder Methods)
Dunder methods are how custom classes plug into Python's syntax β len(), obj[key], for x in obj, ==, +, with, even calling an instance like a function. Implementing the right small set turns a class from "useful" to "feels built-in," and the data model documents every hook the language consults.
| Method | Example | Description |
|---|---|---|
def __init__(self): | Instance initialization β called when object is created. | |
def __str__(self): | Informal string representation β used by str() and print(). | |
def __repr__(self): | β’ Official string representation β should be valid Python when possible β’ fallback for __str__. | |
def __len__(self): | β’ Returns length β called by len()β’ must return non-negative int. | |
def __bool__(self): | β’ Truthiness check β called by bool() and in boolean contextsβ’ falls back to __len__. | |
def __getitem__(self, key): | Indexing operator [] β enables subscript access. | |
def __setitem__(self, k, v): | Item assignment [k] = v β makes object a mutable container. | |
def __delitem__(self, key): | Deletion via del obj[key] β required for full mutable container protocol. | |
def __iter__(self): | Returns an iterator β enables for-loop support and unpacking. | |
def __next__(self): | Gets next value β raises StopIteration when exhausted. | |
def __contains__(self, item): | Membership test in β should return boolean. | |
def __enter__(self): | Context manager protocol β enables with statement. | |
def __add__(self, other): | β’ Addition operator + β return new objectβ’ don't modify self. | |
def __eq__(self, other): | β’ Equality operator == β default compares identityβ’ defining it disables __hash__ by default | |
def __hash__(self): | β’ Makes instance hashable β required to use as dict key or set element β’ must be consistent with __eq__. | |
def __lt__(self, other): | Comparison operators < and > β enables sorting. | |
def __call__(self): | Makes instance callable like a function β enables obj() syntax. | |
def __format__(self, spec): | Custom format spec support β called by format() and f-string {obj:spec} syntax. | |
def __class_getitem__(cls, item): | Enables generic alias syntax MyClass[T] β supports runtime type parameterization. |
Table 10: Exception Handling
Exceptions are Python's primary error-signalling mechanism, with a four-clause structure (try/except/else/finally) and clean chaining via raise ... from .... Python 3.11's ExceptionGroup and except* give the language a way to express multiple concurrent failures β essential for asyncio.TaskGroup and structured-concurrency designs.
| Technique | Example | Description |
|---|---|---|
try: risky()except ValueError: | Catches exceptions β specific types should precede general ones. | |
except (ValueError, KeyError): | Catches multiple types in one clause β tuple of exception classes. | |
except ValueError as e: | Captures the exception object β access message and attributes via e. | |
else: print("success") | Runs if no exception raised in the try block β before finally. | |
finally: cleanup() | β’ Always executes β even if exception raised or return encounteredβ’ for resource cleanup | |
raise ValueError("msg") | Throws an exception β bare raise re-raises the current active exception. | |
class MyError(Exception): | Define new exception types β inherit from Exception or a more specific subclass. | |
raise NewError() from e | Links exceptions β preserves original cause for debugging tracebacks. | |
raise ExceptionGroup("msg", [ValueError(), KeyError()]) | Groups multiple exceptions together β handled with except* (Python 3.11+). | |
except* ValueError as eg: | Catches matching exceptions from an ExceptionGroup β multiple except* clauses can match (Python 3.11+). | |
except: | β’ Catches all exceptions including KeyboardInterrupt β dangerous, hides bugsβ’ avoid |
Table 11: File Operations
File I/O uses a unified open() API parameterized by mode (r/w/a/b/+) and is best paired with with to guarantee cleanup on every exit path. Modern code increasingly leans on pathlib.Path for path manipulation and one-call read_text/write_text shortcuts β and remembers to pass encoding="utf-8" to dodge locale-dependent surprises across operating systems.
| Technique | Example | Description |
|---|---|---|
with open("f.txt") as f: | Context manager β auto-closes file even if an exception occurs. | |
for line in f: | Memory-efficient line iteration β preferred over readlines() for large files. | |
content = f.read() | Reads entire file as string β memory-intensive for large files. | |
line = f.readline() | Reads a single line β includes newline character. | |
lines = f.readlines() | Returns list of all lines β newlines preserved in each element. | |
f.write("text") | Writes string to file β doesn't add newline automatically. | |
f.writelines(lines) | Writes a sequence of strings β no newlines added automatically. | |
open("f.txt", "r") | Read mode β raises FileNotFoundError if file does not exist. | |
open("f.txt", "w") | Write mode β truncates existing file or creates new. | |
open("f.txt", "a") | β’ Append mode β adds to end of existing file β’ creates if absent | |
open("f.bin", "rb") | β’ Binary mode β for non-text files β’ returns bytes objects | |
open("f.txt", "x") | Exclusive creation β raises FileExistsError if file already exists. | |
Path("f.txt").read_text(encoding="utf-8") | β’ Object-oriented path API β cleaner than os.pathβ’ copy()/move() added in 3.14. | |
f = open("f.txt", encoding="utf-8") | Always specify encoding="utf-8" to avoid locale-dependent surprises on Windows. |
Table 12: Modules and Imports
Python's import system stitches code into namespaces using sys.path (search list), sys.modules (cache), and a finder/loader stack you can extend. Idiomatic code prefers explicit import over from X import *, uses relative imports inside packages, and guards script-only code behind if __name__ == "__main__": so the same file works as both a library and a script.
| Technique | Example | Description |
|---|---|---|
import math | Imports entire module β access via math.func(). | |
from math import sqrt | Imports specific names β directly accessible without module prefix. | |
import numpy as np | Aliases module to a shorter name for convenience. | |
if __name__ == "__main__": | Checks if script is run directly vs imported β guards executable code. | |
from . import sibling | Within packages β dot notation for current/parent package. | |
pkg/__init__.py | Makes directory a package β can initialize the package and control public API. | |
sys.path.append(dir) | Module search paths β modify to add custom locations. | |
importlib.import_module(name) | Dynamic imports β import by string name at runtime. | |
from math import * | β’ Imports all public names β discouraged β’ pollutes namespace and hides origins |
Table 13: Common Built-in Functions
The built-ins show up in nearly every Python program β len, range, enumerate, zip, map, filter, sum, sorted, min/max, all/any, isinstance. Mastering their key= arguments, lazy-iterator returns, and edge cases (vacuous all([]), zip truncation, input always returning str) keeps day-to-day code short and correct.
| Function | Example | Description |
|---|---|---|
len([1, 2, 3]) | Returns length of sequence or collection β calls __len__. | |
range(start, stop, step) | Generates arithmetic sequence β stop is exclusive. | |
enumerate(items, start=0) | Adds counter to iterable β returns (index, value) pairs. | |
zip(list1, list2) | β’ Pairs elements from iterables β stops at shortest input β’ strict=True raises if lengths differ (3.10+). | |
map(func, iterable) | Applies function to each element β returns lazy iterator. | |
filter(predicate, items) | Filters elements where predicate is truthy β lazy iterator. | |
sorted(items, key=func) | β’ Returns new sorted list β doesn't modify original β’ reverse=True for descending | |
sum(numbers, start=0) | Sums a numeric iterable β optional starting value. | |
min(items, key=func) | Returns smallest/largest element β optional key function. | |
all([True, True, False]) | Returns True if all elements truthy or iterable is empty (vacuously true). | |
any([False, False, True]) | Returns True if any element truthy. | |
reversed(seq) | Returns a reverse iterator β doesn't modify original. | |
isinstance(obj, type) | β’ Checks object type β accepts tuple of types β’ works with inheritance | |
type(obj) | Returns object's exact type β for checking, prefer isinstance(). | |
getattr(obj, "name", default) | Dynamic attribute access β getattr supports a default, avoids AttributeError. | |
vars(obj) | β’ vars() returns __dict__β’ dir() lists all attributes and methods of an object | |
abs(-5), divmod(17, 5) | β’ abs() returns magnitudeβ’ divmod(a, b) returns (quotient, remainder) as a tuple | |
hex(255) β "0xff" | Converts integers to hexadecimal/octal/binary string representations. | |
callable(func) | Returns True if object appears callable (has __call__). | |
hash("hello") | β’ Returns integer hash of a hashable object β’ consistent within a process | |
id(obj) | Returns object's memory address β guaranteed unique for its lifetime. | |
input("Enter: ") | Reads a line from stdin β always returns string. | |
print(*values, sep=" ", end="\n") | Writes to stdout β customizable separator and line ending. |
Table 14: Itertools Module
itertools is Python's grab-bag of iterator-combining building blocks β composable, lazy, and implemented in C for speed. The module covers infinite generators (count, cycle), combinatorics (combinations, permutations, product), grouping by adjacent runs (groupby), windowing (pairwise, batched), and reduction (accumulate).
| Function | Example | Description |
|---|---|---|
chain(it1, it2) | Concatenates iterables β flattens multiple iterables into single iterator. | |
chain.from_iterable(nested) | Flattens one level of nesting lazily β like chain(*nested) without unpacking. | |
islice(it, start, stop) | Slices an iterator β doesn't support negative indices. | |
compress('ABCDEF', [1,0,1,0,1,1]) | Filters data by a boolean selector iterable β yields A, C, E, F. | |
filterfalse(lambda x: x<5, [1,4,6,3,8]) | Yields elements where predicate is false β opposite of filter(). | |
starmap(pow, [(2,5), (3,2)]) | Applies function with arguments unpacked from each tuple in iterable. | |
pairwise([1, 2, 3]) | Returns overlapping pairs of consecutive elements β (1,2), (2,3) (Python 3.10+). | |
batched(range(10), 3) | Splits iterable into fixed-size tuples β last batch may be shorter (Python 3.12+). | |
groupby(items, key=func) | Groups consecutive elements by key β input must be sorted by same key first. | |
accumulate(nums, func) | β’ Running totals or reductions β default is addition β’ accepts any binary function | |
takewhile(pred, it) | Yields elements while predicate is true β stops at first false. | |
dropwhile(pred, it) | Skips elements while predicate is true β then yields all remaining. | |
tee(iterable, n=2) | Splits one iterator into n independent iterators β use before an iterator is consumed. | |
zip_longest(a, b, fillvalue=None) | Like zip() but continues to the longest input, filling shorter ones with fillvalue. | |
combinations(items, r) | All r-length combinations β order doesn't matter, no repeated elements. | |
combinations_with_replacement('AB', 2) | All r-length combinations allowing repeated elements β yields AA, AB, BB. | |
permutations(items, r) | All r-length permutations β order matters, no repeated elements. | |
product(a, b) | Cartesian product β equivalent to nested for-loops. | |
count(start=0, step=1) | Infinite counter β useful with zip() or takewhile(). | |
cycle([1, 2, 3]) | Repeats iterable infinitely β saves copy of all elements in memory. | |
repeat(10, times=3) | Repeats object n times β infinite if times omitted. |
Table 15: Decorators
Decorators wrap a function or class to add behavior without changing the callsite. The syntax @decorator is sugar for func = decorator(func), extending naturally to parameterized decorators (three nesting levels) and to stacking multiple decorators (applied bottom-up). functools.wraps is mandatory in every wrapper to preserve the original's metadata.
| Technique | Example | Description |
|---|---|---|
def func(): | Wraps function to modify behavior β sugar for func = decorator(func). | |
def deco(f): def wrap(): return f() return wrap | Returns a wrapper function that replaces the original. | |
def wrapper(): | Preserves function metadata ( __name__, __doc__, __wrapped__) β use inside every wrapper. | |
def func(): | Returns a decorator β three-level nesting: deco(arg)(func). | |
def f(): | Multiple decorators applied bottom-up: deco1(deco2(f)). | |
class MyClass: | Modifies or replaces a class β callable receives and returns the class. | |
| Memoizes function results with LRU eviction β cache_info() reports hits and misses. | |
| Unbounded memoization β faster than lru_cache(None) as no eviction overhead (Python 3.9+). | |
def value(self): | Computes property once per instance and caches as a normal attribute β delete attribute to reset (Python 3.8+). | |
class C: | Generates all comparison methods from just __eq__ and one ordering method (__lt__, __le__, __gt__, or __ge__). | |
def method(): | Built-in decorators: @classmethod, @staticmethod, @property. |
Table 16: Context Managers
Context managers β driven by __enter__/__exit__ (or __aenter__/__aexit__ for async) β guarantee deterministic resource cleanup even if the block raises. The contextlib module makes new managers trivial via the @contextmanager generator decorator and packages handy ones like suppress, closing, and the dynamic-composition ExitStack.
| Technique | Example | Description |
|---|---|---|
with open("f") as f: | Ensures resource cleanup β calls __enter__ and __exit__. | |
with open("a") as f1, open("b") as f2: | Manages multiple resources β left-to-right acquisition, right-to-left release. | |
def ctx(): yield | Creates a context manager from a generator β yield separates setup from teardown. | |
def __enter__(self): return self | Full protocol implementation β __exit__ receives (exc_type, exc_val, exc_tb). | |
with suppress(FileNotFoundError): | Ignores specified exceptions β cleaner than try: ... except: pass. | |
with closing(obj): | Calls close() on exit β for objects without a native context manager. | |
with ExitStack() as stack: | Manages a variable number of context managers dynamically. |
Table 17: Async/Await (Asyncio)
asyncio delivers cooperative single-threaded concurrency: many waiting coroutines, one running at a time, no blocking. await is the only yield point β every awaited call must be non-blocking β and Python 3.11+ adds structured concurrency via TaskGroup plus deadline-based timeout(). The synchronization primitives (Lock, Event, Semaphore, Queue) mirror the threading module but are awaitable, not blocking.
| Technique | Example | Description |
|---|---|---|
async def fetch(): | Defines a coroutine function β must be awaited or scheduled as a task. | |
result = await coro() | Suspends coroutine β yields control to event loop until result is ready. | |
asyncio.run(main()) | β’ Entry point β creates event loop and runs coroutine β’ closes loop on completion | |
task = create_task(coro()) | Schedules coroutine to run concurrently with other tasks. | |
async with TaskGroup() as tg: tg.create_task(coro()) | Structured concurrency β auto-cancels remaining tasks on failure (Python 3.11+). | |
await gather(coro1(), coro2()) | Runs multiple coroutines concurrently β waits for all to complete. | |
async with asyncio.timeout(5): | Context manager with deadline β raises TimeoutError if exceeded (Python 3.11+). | |
await wait_for(coro(), timeout=5) | Adds timeout to a coroutine β raises TimeoutError if exceeded. | |
async with asyncio.Lock(): | Mutex lock for async tasks β prevents concurrent access to shared state. | |
event = asyncio.Event()await event.wait() | Notifies multiple tasks that something happened β set(), clear(), wait(). | |
async with asyncio.Semaphore(10): | Limits number of concurrent coroutines accessing a resource. | |
q = asyncio.Queue()await q.put(x)x = await q.get() | FIFO queue for producer-consumer patterns β task_done() + join() for completion tracking. | |
await asyncio.sleep(1) | Non-blocking sleep β yields control to other coroutines. | |
async for item in async_iter: | Iterates over an async iterable β calls __aiter__ and __anext__. | |
async with resource: | Async context manager β awaits __aenter__ and __aexit__. |
Table 18: Type Hints
Type hints are runtime metadata that static checkers (mypy, pyright, pyre) consume to find bugs before they ship. PEP 585 (Python 3.9) made built-in generics work directly (list[int]), PEP 604 (3.10) introduced int | None unions, PEP 695 (3.12) added inline generic-parameter syntax, and PEP 649/749 (3.14) introduced deferred evaluation β annotations are no longer evaluated at import time, dramatically improving startup performance.
| Technique | Example | Description |
|---|---|---|
x: int = 5 | Annotates variable type β not enforced at runtime. | |
def f(x: int) -> str: | Parameter and return types β used by type checkers like mypy and pyright. | |
items: list[int]d: dict[str, int] | Use built-in types directly as generics β no List/Dict imports needed (Python 3.9+). | |
x: int | str | β’ Multiple allowed types β modern |β’ syntax replaces Union[int, str] (Python 3.10+). | |
x: Optional[int] = None | β’ Shorthand for Union[T, None] β prefer T |β’ None in new code | |
class Config(TypedDict): host: str port: int | Typed dict with specific key/value types β enables type checking on dict literals. | |
f: Callable[[int], str] | Function type β list of param types then return type. | |
class Sized(Protocol): def __len__(self): ... | Structural subtyping β duck typing with static type checking. | |
x: Literal["a", "b"] | Restricts to specific values β useful for discriminated unions. | |
T = TypeVar('T') | Generic type variable β for parametric polymorphism in functions and classes. | |
def f[T](x: T) -> T: | Inline generic type variables on functions and classes β replaces TypeVar (Python 3.12+). | |
type Vector = list[float] | Declares a type alias with lazy evaluation β replaces TypeAlias annotation (Python 3.12+). | |
P = ParamSpec('P') | Captures the parameter types of a callable β essential for typing decorators that preserve signatures. | |
def f(**kwargs: Unpack[Config]): | Types **kwargs using a TypedDict β enables per-key type checking (Python 3.12+). | |
x: Any | β’ Disables type checking β avoid when possible β’ escape hatch | |
def is_str(x) -> TypeIs[str]: | Narrows type in both if/else branches β safer than TypeGuard (Python 3.13+). | |
def method(self): | Marks method as overriding parent β type checkers flag mismatches (Python 3.12+). | |
def f(x: MyClass) -> None: | In Python 3.14+ annotations are not evaluated at import time β forward references work natively without quotes. |
Table 19: Regular Expressions
The re module exposes a single regex engine through both functional (re.search, re.findall, re.sub) and compiled (re.compile(...)) APIs. The biggest pitfalls are re.match vs re.search (anchored vs unanchored) and forgetting r"..." raw strings β without them, Python's own backslash processing eats half your pattern before the engine sees it.
| Function | Example | Description |
|---|---|---|
re.search(r"\d+", s) | Searches anywhere in string β returns first match object or None. | |
re.match(r"\d+", s) | Matches at start of string only β returns match object or None. | |
re.fullmatch(r"\d+", s) | Matches entire string β both ^ and $ are implicit. | |
re.findall(r"\d+", s) | Returns list of all matches β non-overlapping strings. | |
re.finditer(r"\d+", s) | Returns iterator of match objects β memory-efficient for large inputs. | |
re.sub(r"\d+", "X", s) | Replaces matches β accepts function as replacement for dynamic substitutions. | |
re.split(r"\s+", s) | Splits by pattern β preserves groups in result if pattern has groups. | |
p = re.compile(r"\d+") | Precompiles pattern β faster for reuse across many strings. | |
m.group(1) | Captures subpatterns β group(0) is entire match, group(1) first capture. | |
(?P<name>\d+) | Named capture β access via m.group('name') or m.groupdict(). | |
r"\d+?" | ? after quantifier β matches as few characters as possible. | |
r"\d+(?= px)" | Zero-width assertions β (?=...) lookahead, (?<=...) lookbehind β don't consume chars. | |
re.search(r"a", s, re.I) | β’ Case-insensitive matching β combine flags with re.I |β’ re.M. | |
re.search(r".+", s, re.S) | Makes . match newlines too β useful for multi-line text blocks. | |
re.search(r"^word", s, re.M) | ^ and $ match start/end of each line, not just the string. | |
r"\d+" | Prefix with r β avoids double-escaping backslashes in patterns. |
Table 20: Dataclasses and Modern Class Features
@dataclass (Python 3.7+) generates __init__, __repr__, and __eq__ from type-annotated attributes, with knobs for frozen, slots, and kw_only to fit specific use cases. For runtime validation and coercion at system boundaries, the ecosystem leans on pydantic; for richer feature sets without the validation cost, on attrs.
| Technique | Example | Description |
|---|---|---|
class Point: x: float y: float | Auto-generates __init__, __repr__, __eq__ β less boilerplate (Python 3.7+). | |
x: int = 0 | Default values β mutable defaults must use field(default_factory=...). | |
items: list = field(default_factory=list) | Customizes field behavior β prevents shared mutable defaults across instances. | |
| Makes instances immutable β enables hashing for use as dict keys. | |
| Generates __slots__ for reduced memory β prevents dynamic attribute creation (Python 3.10+). | |
| Forces keyword-only arguments in __init__ β prevents positional mistakes (Python 3.10+). | |
def __post_init__(self): | Runs after __init__ β for computed fields or validation. | |
temp: InitVar[int] | Init-only variable β not stored as field, available in __post_init__. | |
asdict(obj) | Converts dataclass to dict/tuple β deep-copies nested dataclasses. | |
class C: | Third-party alternative β more features than dataclasses (validators, converters, slots by default). | |
class User(BaseModel): | Data validation library β runtime type checking, coercion, and JSON schema generation. |
Table 21: Enum Module
The enum module provides a way to define named constant sets with distinct identity, preventing typos and magic-string comparisons. Python 3.11 added StrEnum and IntEnum auto-values that produce the lowercased member name, and Python 3.12 improved the repr of enum members and simplified subclassing.
| Type | Example | Description |
|---|---|---|
class Color(Enum): RED = 1 GREEN = 2 | Base class for enumerations β members have unique identity and are accessed as Color.RED. | |
RED = auto() | Automatically assigns values β default is sequential integers starting at 1. | |
class Status(IntEnum): OK = 200 | Enum whose members are also int β compatible with integer APIs. | |
class Direction(StrEnum): NORTH = auto() | Members are also str β auto() generates the lowercased member name (Python 3.11+). | |
class Perm(Flag): READ = auto() WRITE = auto() | β’ Members support bitwise operations β combine with |β’ , test with in. | |
class Mode(IntFlag): R = 4 W = 2 | Flag + int compatibility β members behave as integers for system calls and bitmasks. | |
list(Color) | Enumerates all members in definition order. | |
Color(1), Color["RED"] | Access by value ( Color(1)) or by name (Color["RED"]). | |
Color.RED.value, Color.RED.name | Access the raw value or the member name string. |
Table 22: Collections Module
The collections module provides specialized container datatypes that extend Python's built-in dict, list, set, and tuple. deque is the go-to for O(1) queue operations, OrderedDict retains its usefulness for LRU implementations despite regular dicts being ordered since 3.7, and Counter eliminates a common tally-building loop pattern entirely.
| Type | Example | Description |
|---|---|---|
from collections import dequedq = deque([1,2,3], maxlen=5) | β’ Double-ended queue β O(1) append and pop on both ends β’ list.pop(0) is O(n). | |
dq.appendleft(0)dq.popleft() | Efficient left-side operations β core advantage over list for queue usage. | |
deque(maxlen=10) | β’ Bounded deque β oldest items auto-discarded when full β’ perfect for sliding windows | |
defaultdict(list) | Dict that auto-creates missing keys using a factory function. | |
Counter("abracadabra") | Dict subclass for counting hashable objects β most_common(n) returns top-n items. | |
c1 + c2, c1 - c2, c1 & c2 | β’ Supports +, -, & (intersection), |β’ (union) β results keep only positive counts. | |
c.total() | Returns sum of all counts (Python 3.10+). | |
Point = namedtuple('Point', 'x y') | Tuple with named fields β immutable, memory-efficient alternative to a class. | |
OrderedDict() | β’ Dict that remembers insertion order and supports move_to_end()β’ still useful for LRU caches | |
od.move_to_end("key") | Moves key to end (or beginning with last=False) β key primitive for LRU cache implementation. | |
ChainMap(local, global_, builtins) | β’ Groups multiple dicts β searches sequentially without copying β’ write goes to first map | |
class MyDict(UserDict): | Subclass-friendly wrappers around dict/list β safer to subclass than the built-ins directly. |
Table 23: Concurrency
Python offers three concurrency models: threading (shared memory, GIL-limited for CPU work, good for I/O), multiprocessing (separate processes, true parallelism, higher overhead), and asyncio (cooperative single-thread, ultra-low overhead, requires async-aware code). concurrent.futures wraps both threading and multiprocessing behind one uniform executor interface; Python 3.14 adds InterpreterPoolExecutor for sub-interpreter concurrency without the IPC overhead of full processes.
| Technique | Example | Description |
|---|---|---|
with ThreadPoolExecutor(max_workers=4) as ex: fut = ex.submit(func, arg) | β’ Thread pool β best for I/O-bound tasks β’ GIL limits CPU parallelism | |
with ProcessPoolExecutor() as ex: fut = ex.submit(func, arg) | β’ Process pool β true CPU parallelism β’ data is pickled between processes | |
list(ex.map(func, items)) | Parallel map β returns results in submission order, raises first exception encountered. | |
fut.result(timeout=5) | Blocks until result available β re-raises any exception thrown by the worker. | |
for f in as_completed(futures): | Yields futures as they complete β better throughput than waiting in submission order. | |
with InterpreterPoolExecutor() as ex: | Runs tasks in sub-interpreters β true parallelism without pickle overhead (Python 3.14+). | |
t = Thread(target=f, args=(1,))t.start(); t.join() | Spawns a native OS thread β use daemon=True to die with main thread. | |
lock = Lock()with lock: | Mutex for shared state β with lock: is preferred (auto-releases on exceptions). | |
e = Event()e.set(); e.wait() | Allows threads to signal each other β wait() blocks until set(). | |
sem = Semaphore(3) | Limits concurrent access to n threads β acquire() decrements, release() increments. | |
with Pool() as pool: pool.map(func, items) | Higher-level multiprocessing API β automatically manages worker process lifecycle. | |
q = mp.Queue()q.put(x); q.get() | Process-safe queue β IPC via pickle across process boundaries. | |
python3.14 -X gil=0 | Python 3.14 makes free-threading production-ready (PEP 779) β true thread parallelism possible. |
Table 24: Logging Module
Python's logging is a hierarchical system: every logger is a node in a tree rooted at the root logger, and events propagate upward unless propagate=False. Application code should always call logging.getLogger(__name__), let libraries configure nothing themselves, and leave root-level configuration to the application entry point.
| Technique | Example | Description |
|---|---|---|
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s") | β’ Configures root logger β one-time call for simple scripts β’ must be before first log call | |
logger = logging.getLogger(__name__) | β’ Gets or creates a named logger β hierarchy via dot notation β’ always use __name__. | |
logger.debug("...")logger.info("...")logger.warning("...")logger.error("...")logger.critical("...") | Five levels: DEBUG < INFO < WARNING < ERROR < CRITICAL β only events at or above set level are emitted. | |
h = logging.StreamHandler()logger.addHandler(h) | Outputs to stderr (default) or any stream β standard handler for console output. | |
h = logging.FileHandler("app.log") | Writes to a file β use RotatingFileHandler for size-limited rotation. | |
RotatingFileHandler("app.log", maxBytes=1e6, backupCount=3) | Rotates log file when it reaches maxBytes β keeps backupCount backups. | |
fmt = Formatter("%(asctime)s - %(name)s - %(message)s")h.setFormatter(fmt) | Controls log record format β standard attributes include asctime, name, levelname, message. | |
except Exception: logger.exception("Error") | Logs at ERROR level plus the full stack trace β use inside except blocks. | |
logger.propagate = False | Stops log records bubbling up to parent loggers β avoids duplicate output. | |
logging.config.dictConfig(cfg) | Configures logging from a dict or file β preferred for production over basicConfig. | |
adapter = LoggerAdapter(logger, {"req_id": id}) | Adds contextual data to every log call without modifying the message format. |
Table 25: Virtual Environments and Packaging
Isolation is the first principle: one project, one environment, so dependency versions never interfere. venv is the built-in option (zero install, always available), while uv (Astral) is a fast Rust-based alternative that manages both environments and Python installations with near-instant dependency resolution.
| Tool | Example | Description |
|---|---|---|
python -m venv .venv | Creates a virtual environment β installs pip + copies/symlinks interpreter. | |
source .venv/bin/activate.venv\Scripts\activate | Activates environment β modifies PATH so python/pip point to venv. | |
pip install requestspip install -r requirements.txt | Installs packages β -r installs from requirements file. | |
pip freeze > requirements.txt | Snapshots current installed packages with pinned versions. | |
uv init example | Creates a new project with pyproject.toml β fast Rust-based tool (Astral). | |
uv run script.py | Runs script in an isolated, auto-created environment β no manual activation needed. | |
uv add requests | Adds dependency to pyproject.toml and updates lockfile atomically. | |
uv sync | Installs dependencies from lockfile β reproduces exact environment. | |
uv python install 3.12 | Downloads and installs a specific Python version β managed alongside venv. | |
[project]name = "myapp"requires-python = ">=3.11" | β’ Modern packaging standard β replaces setup.pyβ’ supported by pip, uv, poetry, flit | |
pyenv install 3.11.5pyenv local 3.11.5 | Manages multiple Python versions side-by-side β sets .python-version file per directory. | |
poetry new projectpoetry add requests | Package manager with lockfile and publishing support β poetry install reproduces env. |
Table 26: Advanced Patterns and Best Practices
These patterns represent idiomatic Python thinking: prefer iteration over indexing, exploit descriptors and __slots__ for performance-critical classes, compose with functools.partial (and Python 3.14's Placeholder for gap filling), and exploit generators for lazy pipelines that process data without materializing everything in memory.
| Technique | Example | Description |
|---|---|---|
evens = (x for x in data if x%2==0)result = sum(evens) | β’ Chains generators lazily β never materializes intermediate lists β’ memory-efficient for large datasets | |
double = partial(mul, 2) | Pre-fills arguments β creates specialized callable from a general function. | |
f = partial(pow, ..., 2) | Marks positional gaps in partial() that callers must fill β ... is the Placeholder (Python 3.14+). | |
reduce(lambda a,b: a+b, nums) | Folds a sequence left-to-right into a single value. | |
def __get__(self, obj, type): | Implements per-attribute access β foundation for property, classmethod, staticmethod. | |
__slots__ = ("x", "y") | Replaces per-instance __dict__ with fixed memory layout β reduces RAM and speeds attribute access. | |
while chunk := f.read(8192): | β’ Assignment expression β assigns and evaluates in one step β’ avoids repeated calls | |
def f(a, b, /, c): | β’ / separator β a, b can only be passed by positionβ’ prevents API-breaking renames | |
def f(*, a, b): | * separator β a, b must be passed by keyword. | |
class Meta(type): def __new__(mcs, ...): | Controls class creation β used by ORMs, ABCs, and plugin registries. | |
def __init_subclass__(cls, **kw): | Hook called when a class is subclassed β simpler plugin registration than metaclasses. | |
def __new__(cls): if not cls._instance: cls._instance = super().__new__(cls) return cls._instance | Ensures one instance via __new__ β thread-safe version requires a lock. | |
tmpl = t"Hello {name}" | β’ Like f-strings but deferred β returns a Template object instead of a stringβ’ enables safe HTML/SQL generation (Python 3.14+). | |
def f() -> MyClass: | β’ Annotations are not evaluated at import time in Python 3.14+ β forward references require no quotes β’ use annotationlib to evaluate explicitly | |
import concurrent.interpreters | New in Python 3.14 (PEP 734) β runs code in isolated sub-interpreters with true parallelism via InterpreterPoolExecutor. |