PYTHON ADVANCED: PROFESSIONAL ENGINEERING MASTERY / L01DECORATORS MASTERY: FROM CLOSURES TO CLASS DECORATORS
课程 · 12 · 01 / 12
LESSON 01 · ADVANCED · 60 MIN · ◆ 4 INSTRUMENTS

Decorators Mastery: From Closures to Class Decorators

Master Python decorators from the ground up. Understand closures, build function and class decorators, use functools, and apply real-world patterns.

TIP

Learning Objectives: After this lesson, you'll understand closures deeply, build function and class decorators from scratch, use functools effectively, and apply real-world decorator patterns in production code.

How Decorators Transform Functions

Before diving into code, let's visualize what decorators actually do. A decorator wraps a function, adding behavior before and/or after the original function runs.

FIG. 02Flow Diagram
INTERACTIVE
LOADING INSTRUMENT
Fig. 02Interactive flow diagrams, timelines, and process visualizations

When you write @timer above a function, Python replaces that function with the wrapped version. The original function still exists—it's just called from inside the wrapper.

The Foundation: Understanding Closures

TIP

🧠 See it before reading the math: open Python Tutor and paste a counter-factory like def make_counter():\n count = 0\n def increment():\n nonlocal count\n count += 1\n return count\n return increment\n\nc = make_counter()\nc(); c(); c(). The arrows pointing from increment back into the closed-over count cell make closures finally feel concrete.

Before diving into decorators, we need to solidify our understanding of closures—the mechanism that makes decorators work.

What is a Closure?

A closure is a function that remembers values from its enclosing scope even after that scope has finished executing. Let's visualize how scope works:

FIG. 04Scope Visualizer
INTERACTIVE
LOADING INSTRUMENT
Fig. 04Interactive visualization of variable scope

Interact with the visualizer above to see how variables are captured in different scopes. Now let's see closures in action:

FIG. 06Python Code Executor
INTERACTIVE
LOADING INSTRUMENT
Fig. 06Interactive Python code execution environment

Visualizing Closure Memory

Closures capture variables by reference, not by value. This visualization shows how multiple closures can share the same memory cell:

FIG. 08Flow Diagram
INTERACTIVE
LOADING INSTRUMENT
Fig. 08Interactive flow diagrams, timelines, and process visualizations
FIG. 10Python Code Executor
INTERACTIVE
LOADING INSTRUMENT
Fig. 10Interactive Python code execution environment

Function Decorators: The Basics

A decorator is simply a function that takes a function as input and returns a new function. Let's trace through the execution:

The Call Stack During Decoration

FIG. 12Function Call Stack
INTERACTIVE
LOADING INSTRUMENT
Fig. 12Visualization of function call stack and scope

Use the call stack visualizer above to understand how function calls nest. Now let's see the actual decorator pattern:

The Manual Way

FIG. 14Python Code Executor
INTERACTIVE
LOADING INSTRUMENT
Fig. 14Interactive Python code execution environment

The @ Syntax

The @decorator syntax is just syntactic sugar. Here's how stacked decorators work:

FIG. 16Flow Diagram
INTERACTIVE
LOADING INSTRUMENT
Fig. 16Interactive flow diagrams, timelines, and process visualizations
FIG. 18Python Code Executor
INTERACTIVE
LOADING INSTRUMENT
Fig. 18Interactive Python code execution environment

Preserving Function Metadata with functools

FIG. 20Python Code Executor
INTERACTIVE
LOADING INSTRUMENT
Fig. 20Interactive Python code execution environment

Decorators with Arguments

Creating decorators that accept arguments requires an extra level of nesting. Let's visualize this three-layer structure:

FIG. 22Flow Diagram
INTERACTIVE
LOADING INSTRUMENT
Fig. 22Interactive flow diagrams, timelines, and process visualizations
FIG. 24Python Code Executor
INTERACTIVE
LOADING INSTRUMENT
Fig. 24Interactive Python code execution environment

Class-Based Decorators

Decorators can also be implemented as classes using __call__.

FIG. 26Flow Diagram
INTERACTIVE
LOADING INSTRUMENT
Fig. 26Interactive flow diagrams, timelines, and process visualizations
FIG. 28Python Code Executor
INTERACTIVE
LOADING INSTRUMENT
Fig. 28Interactive Python code execution environment

Decorating Classes

Decorators can also modify classes, not just functions.

FIG. 30Python Code Executor
INTERACTIVE
LOADING INSTRUMENT
Fig. 30Interactive Python code execution environment

Real-World Decorator Patterns

Authentication and Authorization

FIG. 32Flow Diagram
INTERACTIVE
LOADING INSTRUMENT
Fig. 32Interactive flow diagrams, timelines, and process visualizations
FIG. 34Python Code Executor
INTERACTIVE
LOADING INSTRUMENT
Fig. 34Interactive Python code execution environment

Caching and Memoization

FIG. 36Python Code Executor
INTERACTIVE
LOADING INSTRUMENT
Fig. 36Interactive Python code execution environment

Input Validation

FIG. 38Python Code Executor
INTERACTIVE
LOADING INSTRUMENT
Fig. 38Interactive Python code execution environment

Advanced: Decorators That Work on Methods and Functions

FIG. 40Python Code Executor
INTERACTIVE
LOADING INSTRUMENT
Fig. 40Interactive Python code execution environment

Practice Exercises

Exercise 1: Rate Limiter Decorator

FIG. 42Python Code Executor
INTERACTIVE
LOADING INSTRUMENT
Fig. 42Interactive Python code execution environment

Exercise 2: Deprecation Warning Decorator

FIG. 44Python Code Executor
INTERACTIVE
LOADING INSTRUMENT
Fig. 44Interactive Python code execution environment

Key Takeaways

ConceptDescription
ClosuresFunctions that capture and remember variables from enclosing scope
@wrapsPreserves original function's metadata when decorating
Decorator argumentsRequire factory function that returns the actual decorator
Class decoratorsUse __call__ to make instances callable
Method decoratorsNeed careful handling of self parameter
lru_cacheBuilt-in memoization with LRU eviction

Common Decorator Patterns

  1. Logging/Tracing - Track function calls and results
  2. Timing - Measure execution time
  3. Caching - Store results for repeated calls
  4. Retry - Automatically retry on failure
  5. Validation - Check inputs before execution
  6. Authentication - Verify access permissions
  7. Rate limiting - Control call frequency

Next Steps

In the next lesson, we'll explore Generators and Iterators—learn the iterator protocol, build generators with yield, understand lazy evaluation, and see how generators relate to coroutines and async programming.


Ready to master lazy evaluation? Generators await in the next lesson!


Further Reading

Visualize It

  • Python Tutor — paste a decorator with closure capture and step through. The "wait, the inner function remembers func?" moment lands instantly.

Official Docs

Tutorials

Production Patterns

Books

  • Book: Fluent Python (2nd ed.) — Chapter 9 ("Decorators and Closures"). The definitive treatment.
  • Book: Effective Python — Items 26–27 cover @functools.wraps and decorator composition.