7 routes42 sections324 units

Unit 3.2 · about 3 h

11 / 324

Argument binding, scope and closures

Mutable defaults and late-bound closures leak state between calls. Call semantics decide exactly what a caller can observe.

  • explain

You can now

  • Explain positional, keyword, default, *args, **kwargs, positional-only and keyword-only binding, including when defaults are evaluated.
  • Explain block scope, global and nonlocal, and closure capture with the late-binding rule.
  • Predict UnboundLocalError and shared-mutable-default behavior in unseen code.

Covers

  • Argument binding, evaluation time and mutable defaults
  • Lexical scope, closures and captured state

Study, in this order

6 steps

  1. Argument binding forms
    Stas' Python Cookbook - selected path

    Functions: Arguments (positional, keyword, defaults, *args/**kwargs, positional-only and keyword-only); the mutable-default bad/good pair

  2. Call by assignment
    Stas' Python Cookbook - selected path

    Functions: Pass-by-object-reference (mutating a mutable argument versus rebinding a name)

  3. Closures and late binding
    Stas' Python Cookbook - selected path

    Functions: Closures (the nonlocal counter); the late-binding trap with the default-argument bind

  4. Binding and resolution of names
    Python language reference

    Sections 4.2.1 and 4.2.2: binding constructs, block-wide locals, UnboundLocalError, global and nonlocal, the class-block scope rule

  5. Default Arguments
    AlgoMaster Python - structured revision

    The Default Arguments lesson and Exercise: Default Arguments; recall after the cookbook pass

  6. Closures
    AlgoMaster Python - structured revision

    The Closures lesson and Exercise: Closures; predict each output before checking

Focus on

  • Defaults evaluate once at function definition time. The None sentinel plus a fresh list inside the body is the standard fix.
  • Arguments pass by assignment: rebinding a parameter is invisible to the caller, while mutating a mutable argument is visible.
  • Closures capture variables, not values. Loop closures share the final value; a default argument binds the current one.
  • A name bound anywhere in a block is local everywhere in it. Reading it before assignment raises UnboundLocalError; global and nonlocal redirect the binding.

Reproduce closed-book

Closed-book, write make_funcs returning three closures over range(3) so each returns its own index, plus a nonlocal counter starting at 0. State that the naive loop version returns [2, 2, 2] on CPython 3.14.4.

Traps

  • Believing closures snapshot values. They read the live cell at call time.
  • Using += on a global without a global statement. Augmented assignment binds, so the name goes local and the read fails.
  • Treating every parameter before * as positional-only. Only parameters before / are; c in def g(a, b, /, c, *, d) still accepts keywords.

Practice

AlgoMaster Python: Exercise: Default Arguments

Exercises 1 to 5, especially Exercise 4: Avoid a Shared List Default and Exercise 5: Distinguish Omitted From None

Do it after the cookbook pass; write the None-sentinel fix from memory.

AlgoMaster Python: Exercise: Closures

Exercises 1 to 5, especially Exercise 3: Inspect Captured Closure Cells, Exercise 4: Update Captured State with Nonlocal and Exercise 5: Avoid Late Binding in a Loop

Predict each closure output on paper before checking.

Self-test

  1. def f(x, acc=[]): acc.append(x); return acc. What do f(1) and f(2) return, and what is the fix?

  2. What does [fn() for fn in [lambda: i for i in range(3)]] give, and why?

  3. x = 10 at module level. def f(): print(x); x = 1. What does f() do?

  4. In def g(a, b, /, c, *, d), which parameters can be passed by keyword?

Completion criterion

Stop when

You fix a mutable-default and a late-binding bug on first reading, and your make_funcs returns [0, 1, 2].

Mark passed, then open 3.3 Only mark this when you can do it without notes.

Leads to

Comes after

Resources for this unit

  • Stas' Python Cookbook - selected path
    Stas Bekmanprimarycourse
    Run Part I on dictionaries, iteration, functions, closures, decorators, classes and context managers; Part II on modules, files, paths, environment and arguments; and Part IV on versions, dependencies, packaging and code quality. Finish by building one src-layout package from a blank directory.
  • Python language reference
    Python Software Foundationrequiredreference
    Check Data model, Execution model, Import system and Exceptions whenever a claim depends on Python semantics. These pages are the authority when the course and a runtime observation disagree.
  • AlgoMaster Python - structured revision
    AlgoMastersupportpractice
    Use Functions, Modules and Packages, OOP, Advanced OOP, Exception Handling, Iterators and Generators, Type Hints and Annotations only after the cookbook pass. Open it for recall practice or a diagnosed weak mechanism, not as a second complete course.

Also in this section

  • Packaging Python Projects
    Python Packaging Authorityrequiredimplementation
    Follow the packaging tutorial once from a blank directory, using a src layout, pyproject.toml, an isolated build and a clean-environment installation test.
  • dataclasses - data classes
    Python Software Foundationreferencereference
    Read the @dataclass parameters (eq, order, frozen, slots), field() with default_factory, frozen instances, post-init processing, replace, asdict and astuple. Use for the validated frozen dataclass in attributes-protocols-dataclasses.
  • typing - type hints and protocols
    Python Software Foundationreferencereference
    Read Protocols for structural typing and runtime_checkable limits, Generics for TypeVar generics, and assert_type for narrowing checks. Use for the Protocol and narrowing parts of type-hints-protocols; PEP 695 syntax itself is in the language reference.
  • gc - cycle garbage collector
    Python Software Foundationreferencereference
    Read the cycle collector interface: collect, get_count, garbage and disable/enable. Use for the cycle-collection and measurement parts of refcounting-gc-weakrefs.
  • weakref - weak references
    Python Software Foundationreferencereference
    Read weak-reference objects (ref callbacks, proxy objects) and the WeakValueDictionary example. Use for the weak-reference part of refcounting-gc-weakrefs.

Quick find

Search Michi

Type to search every route, section, unit, topic and resource.

Enter opens the first result Esc closes

Reference

Keyboard shortcuts

n
Continue to the first unit not passed
j / k
Next / previous unit
1 2 3
Toggle learned, practised, passed
/
Open search
?
Show this help
Esc
Close open panels