Navigation
A complete, densely-packed reference for Python 3.12+. Covers the full language from the ground up — dynamic typing, all built-in data structures, control flow, functions, object-oriented programming, modules, error handling, iterators, generators, decorators, type hints, and Pythonic best practices. Every section includes annotated code examples.
Advertisement
01 — Core Language
what is Python · dynamic & strong typing · variables · LEGB scope
"2" + 2) raises a TypeError instead of silently coercing. This gives prototyping speed without hidden bugs. Inspect types at runtime with type(x) or isinstance(x, int).+=, -=, *=, etc.). Names are case-sensitive and use snake_case by convention. Constants are written in ALL_CAPS (convention only — Python doesn't enforce immutability).global x to write to module scope from inside a function, and nonlocal x to write to an enclosing (non-global) scope — commonly used in closures.🔍 Key insight: Python's LEGB rule is why you can always read a global variable from inside a function, but need the global keyword to assign to it. Without global, the assignment creates a new local variable that shadows the global — a common source of subtle bugs.
Advertisement
02 — Data Types
int · float · complex · str · list · tuple · dict · set · bool
3+4j). Key operators: // floor division, ** exponentiation, % modulo. The math module adds sqrt, log, ceil, floor, trig functions, and more. Use decimal.Decimal for exact decimal arithmetic (finance).{}. Strings support indexing, slicing, concatenation (+), and repetition (*). Key methods: .upper(), .lower(), .strip(), .split(), .join(), .replace(), .startswith(), .find(), .format().Ordered, mutable, allows duplicates. O(1) append and index access; O(n) insert/delete at arbitrary position. The go-to for sequences that need modification.
Ordered, immutable. Slightly faster and more memory-efficient than lists. Use for fixed records, function return values, and as dictionary keys.
Key→value mapping with O(1) average lookup, insert, and delete. Insertion-ordered since Python 3.7. Keys must be hashable (str, int, tuple).
Unordered, unique values only. O(1) membership test (in), union (|), intersection (&), difference (-). Perfect for deduplication and fast membership checks.
collections.defaultdict to avoid key-existence checks, collections.Counter for frequency counting, and collections.deque for efficient O(1) append/pop from both ends of a sequence.03 — Control Flow
if · elif · else · for · while · break · continue · match (3.10+)
if, elif (not "else if"), and else. Python supports a compact ternary expression: x if condition else y. Since Python 3.10, the match statement adds powerful structural pattern matching — it goes far beyond simple switch-case, supporting sequence destructuring, class patterns, and guards.for iterates over any iterable — lists, strings, dicts, ranges, generators. Use range(start, stop, step) for numeric sequences. enumerate() gives index + value together. zip() pairs two iterables in lockstep. break exits the loop early; continue skips to the next iteration. Loops can have an optional else clause that runs if the loop wasn't broken.while repeats as long as a condition remains true. Use while True with a break for interactive loops. The optional else clause runs when the condition becomes false — but not if break was used. Always ensure the loop has a termination condition to avoid infinite loops.Advertisement
04 — Functions
def · *args · **kwargs · lambda · map · filter · comprehensions
def. They support default parameters, keyword arguments, *args (variable positional), and **kwargs (variable keyword). Functions always return a value — omitting return returns None. Always write a docstring on the first line to document purpose, parameters, and return value.lambda creates a single-expression anonymous function. map(), filter(), and sorted(key=...) are the classic higher-order functions, though list comprehensions are usually preferred for readability.for-loops with .append(). Python supports list, dict, set, and generator comprehensions. Pattern: [expr for item in iterable if condition]. Generator comprehensions use () instead of [] and are lazy — they produce values on demand without building the full list in memory.05 — Object-Oriented Programming
classes · __init__ · inheritance · super() · @property · __dunder__
__init__ is the constructor — it runs whenever an instance is created. self refers to the instance. Define class attributes (shared by all instances) separately from instance attributes (unique per object). Always implement __repr__ for useful debugging output.super().__init__(). Override methods in the child to specialise behaviour — Python looks up the MRO (Method Resolution Order) to find the right method. Polymorphism lets different classes respond to the same method name in their own way, enabling flexible, extensible code._name) to signal "internal use" (protected by convention), and double underscore (__name) to trigger name mangling (prevents accidental override in subclasses — not security). The @property decorator turns a method into a readable attribute; @attr.setter adds validated write access — the Pythonic way to implement getters/setters with invariant enforcement.🔍 Dunder methods (magic methods): Python's double-underscore methods let you define how objects behave with operators and built-in functions. Implement __len__ for len(obj), __eq__ for ==, __lt__ for <, __add__ for +, __iter__/__next__ for iteration, and __enter__/__exit__ for with statements. This is how Python's built-in types work under the hood.
Advertisement
06 — Modules & Packages
import · from · __init__.py · stdlib · third-party packages · virtual envs
.py file is a module. Import with import module or from module import name. Packages are directories containing an __init__.py file. The standard library is vast — covering math, file I/O, networking, dates, JSON, CSV, regex, threading, and more — with no pip needed. Third-party packages are installed via pip from PyPI (Python Package Index), which hosts over 500,000 packages.Install with pip install <name>. Best practice: always use a virtual environment (python -m venv .venv) per project to isolate dependencies.
Fast numerical arrays and DataFrames for data analysis. The foundation of all Python data science work.
Publication-quality plotting and statistical visualisation. Seaborn wraps matplotlib with beautiful default styles.
Elegant HTTP clients. requests is the classic sync option; httpx adds async support and HTTP/2.
Web frameworks. FastAPI for high-performance async APIs with automatic docs; Flask for lightweight control.
The most powerful Python ORM. Maps database tables to Python classes and supports all major SQL databases.
The go-to testing framework. Fixtures, parametrize, plugins, and clean assertion introspection make testing productive.
07 — Error Handling & File I/O
try · except · else · finally · raise · custom exceptions · open · pathlib
try / except / else / finally manages error flow. Always catch specific exceptions — avoid bare except: which silently swallows every error including KeyboardInterrupt. else runs only if no exception occurred. finally always runs — perfect for resource cleanup. Raise custom errors by subclassing Exception and adding context.open() to read and write files. Always use a with block (context manager) — it guarantees the file is closed even if an exception occurs. Mode flags: "r" read, "w" write (overwrites), "a" append, "rb"/"wb" binary. Use pathlib.Path for modern, readable, cross-platform path manipulation — it replaces os.path in all new code.json.dump(data, f) / json.load(f) for JSON files, csv.DictReader / csv.DictWriter for CSV, and pickle.dump / pickle.load for serialising Python objects (not for untrusted data).08 — Advanced Patterns
yield · itertools · @wraps · lru_cache · type hints · dataclasses
__iter__() and __next__(). A generator uses yield to produce values one at a time without building the full sequence in memory — it pauses execution at yield and resumes from that exact point on the next call to next(). This makes generators ideal for large datasets, infinite sequences, and streaming pipelines. Generator expressions are even more concise: sum(x**2 for x in range(n)).@name syntax is syntactic sugar for func = decorator(func). Always apply @functools.wraps(func) inside your decorator to preserve the wrapped function's __name__ and __doc__ — critical for debugging and introspection tools.mypy, pyright), and self-documenting code. Python 3.9+ allows built-in generics: list[int], dict[str, Any]. Python 3.10+ uses X | Y union syntax. dataclasses (3.7+) combine type hints with automatic boilerplate generation.09 — Quick Reference
arithmetic · comparison · logical · identity · membership · bitwise · walrus
| Category | Operators | Example | Result |
|---|---|---|---|
| Arithmetic | + - * / // % ** | 2 ** 8 | 256 |
| Comparison | == != < > <= >= | 3 < 5 | True |
| Logical | and or not | x > 0 and x < 10 | bool |
| Identity | is is not | x is None | bool |
| Membership | in not in | "a" in "cat" | True |
| Bitwise | & | ^ ~ << >> | 0b1010 & 0b1100 | 8 |
| Assignment | = += -= *= /= //= %= | x //= 3 | in-place |
| Walrus 3.8+ | := | if (n := len(a)) > 10 | assign & test |
| Dict merge 3.9+ | | |= | a | b | merged dict |
| Type union 3.10+ | | | int | str | union type |
and / or with short-circuit evaluation — a and b doesn't evaluate b if a is falsy. This is used idiomatically: name = user_input or "default".Advertisement
10 — Best Practices
Zen of Python · PEP 8 · idioms · virtual envs · tooling
import this in any Python shell to read all 19 aphorisms. These are the guiding philosophy behind how Python code should be written. Every experienced Python developer has internalised them:
for x in items over for i in range(len(items))"Hello " + name or "%s" % namewith open(...) as f over manual f.open() / f.close()append() in a for-loopx is None over x == None (identity, not equality)if items: over if len(items) != 0:first, *rest = [1, 2, 3, 4]merged = dict_a | dict_bany() / all() over manual boolean loopsenumerate() over manual index counterszip() to iterate two lists simultaneouslypython -m pdb -c continue file.py to drop into the debugger when an exception occurs. In VS Code / PyCharm, set breakpoints visually. For quick inspections, breakpoint() (Python 3.7+) drops into pdb wherever you place it.FAQ
Python is dynamically and strongly typed. Dynamic means types are resolved at runtime — no declarations needed. Strong means Python won't silently coerce incompatible types; adding a string to an integer raises a TypeError. Python 3.5+ supports optional type hints for documentation and tools like mypy, but these are not enforced at runtime.
A list is mutable — you can add, remove, or change elements after creation. A tuple is immutable — once created, its contents cannot be changed. Tuples are slightly faster, use less memory, and can be used as dictionary keys. Use tuples for fixed records and function return values; lists for ordered sequences that need modification.
A decorator is a function that wraps another function to add behaviour without modifying the original. The @syntax is shorthand for func = decorator(func). Use decorators for cross-cutting concerns: logging, timing, caching (@lru_cache), authentication, retry logic, and input validation. The standard library uses them heavily: @property, @staticmethod, @classmethod, @functools.wraps.
A generator uses yield to produce values one at a time instead of building the entire sequence in memory. When execution hits yield, the function pauses and returns the value — resuming from that exact point on the next call to next(). This makes generators ideal for large files, infinite sequences, and streaming pipelines where loading everything at once would exhaust memory.
LEGB is Python's variable name resolution order: Local → Enclosing → Global → Built-in. Python searches each scope until the name is found or a NameError is raised. Use global to write to module-level scope from inside a function, and nonlocal to write to an enclosing (non-global) scope in a closure.
Use @dataclass whenever your class is primarily a container for data fields. Dataclasses automatically generate __init__, __repr__, __eq__, and optionally __hash__, __lt__ (with order=True), and frozen immutability (with frozen=True). They significantly reduce boilerplate for simple value objects, configuration holders, and DTOs (Data Transfer Objects). For classes with significant behaviour/logic, a regular class is often clearer.
Community
Get new Python tutorials, deep-dives, and coding guides delivered to your inbox.
Join readers learning Python from first principles.