Saltar a contenido

Week 1 - Syntax, Values, Names, and the Data Model

1.1 Conceptual Core

  • Everything is an object, including types. type(int) is type and type(type) is type. Functions, modules, classes, exceptions, even None - all objects with attributes, addressable by name.
  • Names are not variables. A "variable" in Python is a binding from a name (in a namespace dict) to an object. Assignment never copies; it rebinds. Function arguments are pass-by-binding (often confusingly called "pass by object reference").
  • The data model is a protocol catalog. Every operator and built-in (len, iter, +, [], with, async with, repr) dispatches to a __dunder__ method. Mastering the data model is mastering the language.

1.2 Mechanical Detail

  • Built-in types you must internalize: int (arbitrary precision), float (IEEE 754 double), bool (subclass of int), str (Unicode, immutable), bytes (immutable), bytearray (mutable), list, tuple, dict (insertion-ordered since 3.7), set, frozenset, None, Ellipsis, NotImplemented.
  • Mutability vs. hashability: hashable ⇔ __hash__ defined and stable ⇔ usable as dict key / set element. Mutable built-ins (list, dict, set) are unhashable on purpose.
  • Identity vs. equality: is checks identity (id(a) == id(b)); == checks __eq__. Small int caching (-5..256) and string interning make is comparisons accidentally work - which is precisely why you must never use is for value comparison except against None, True, False.
  • Truthiness: __bool__ then __len__ then True. Falsy: 0, 0.0, "", b"", [], (), {}, set(), None, False.
  • f-strings (3.6+), debug f-strings (f"{x=}", 3.8+), =-format spec, lazy logging (logger.info("x=%s", x) not logger.info(f"x={x}") - the latter formats even at suppressed levels).

1.3 Lab - "The REPL Audit"

  1. In an interactive session, evaluate: a = [1,2,3]; b = a; b.append(4); print(a). Explain in writing.
  2. x = 256; y = 256; x is y → True. x = 257; y = 257; x is y → may be False. Explain.
  3. Write a class Money with __init__, __repr__, __eq__, __hash__, __lt__. Verify it sorts and deduplicates in a set. Add functools.total_ordering; observe what disappears.
  4. Write a class Vector2 with __add__, __sub__, __mul__ (scalar), __rmul__, __abs__, __iter__, __len__. Verify 2 * v works and list(v) works.

1.4 Idiomatic & Linter Drill

  • Install ruff. Configure with rule sets E, F, W, I, B, UP, SIM, RUF, PL. Run on a sample file; read each finding's URL.
  • Read PEP 8 once. Read PEP 20 (import this) and pin it.

1.5 Production Hardening Slice

  • Initialize a project with uv init. Add ruff and pyright as dev deps. Add pyproject.toml with [tool.ruff] and [tool.pyright] strict configurations. Add a Makefile target make check that runs ruff check, ruff format --check, pyright, pytest. This is the baseline; every subsequent week extends it.

Comments