← 返回 Day 24 正文

Day 24 · 图解

Day 024 — 装饰器进阶 图解

1. 带参数装饰器执行流程

flowchart TD subgraph Code["代码"] C1["@repeat(3)"] C2["def greet(name):"] end subgraph Step1["Step 1: repeat(3)"] S1["repeat(3) 被调用"] S2["返回 decorator<br/>(闭包捕获 n=3)"] end subgraph Step2["Step 2: @decorator"] S3["decorator(greet) 被调用"] S4["创建 wrapper<br/>(闭包捕获 func=greet)"] S5["返回 wrapper<br/>greet = wrapper"] end subgraph Step3["Step 3: greet('Alice')"] S6["调用 wrapper('Alice')"] S7["循环 3 次调用<br/>原始 greet('Alice')"] end C1 --> S1 C2 --> S3 S1 --> S2 S2 --> S3 S3 --> S4 S4 --> S5 S5 -.-> S6 S6 --> S7 style C1 fill:#e3f2fd style C2 fill:#e3f2fd style Step1 fill:#fff3e0 style Step2 fill:#f3e5f5 style Step3 fill:#e8f5e9
flowchart TD
    subgraph Code["代码"]
        C1["@repeat(3)"]
        C2["def greet(name):"]
    end

    subgraph Step1["Step 1: repeat(3)"]
        S1["repeat(3) 被调用"]
        S2["返回 decorator<br/>(闭包捕获 n=3)"]
    end

    subgraph Step2["Step 2: @decorator"]
        S3["decorator(greet) 被调用"]
        S4["创建 wrapper<br/>(闭包捕获 func=greet)"]
        S5["返回 wrapper<br/>greet = wrapper"]
    end

    subgraph Step3["Step 3: greet('Alice')"]
        S6["调用 wrapper('Alice')"]
        S7["循环 3 次调用<br/>原始 greet('Alice')"]
    end

    C1 --> S1
    C2 --> S3
    S1 --> S2
    S2 --> S3
    S3 --> S4
    S4 --> S5
    S5 -.-> S6
    S6 --> S7

    style C1 fill:#e3f2fd
    style C2 fill:#e3f2fd
    style Step1 fill:#fff3e0
    style Step2 fill:#f3e5f5
    style Step3 fill:#e8f5e9

2. 三层嵌套结构详解

graph TD subgraph L1["第一层:参数层"] P1["def repeat(n):"] P2["n = 3<br/>(闭包变量)"] end subgraph L2["第二层:装饰器层"] D1["def decorator(func):"] D2["func = greet<br/>(闭包变量)"] end subgraph L3["第三层:包装器层"] W1["def wrapper(*args, **kwargs):"] W2["执行循环 n 次<br/>调用 func()"] end P1 -->|返回 decorator| P2 P2 -.->|"n 被捕获"| D1 D1 -->|返回 wrapper| D2 D2 -.->|"func 被捕获"| W1 W1 --> W2 style L1 fill:#ffcdd2 style L2 fill:#c8e6c9 style L3 fill:#bbdefb
graph TD
    subgraph L1["第一层:参数层"]
        P1["def repeat(n):"]
        P2["n = 3<br/>(闭包变量)"]
    end

    subgraph L2["第二层:装饰器层"]
        D1["def decorator(func):"]
        D2["func = greet<br/>(闭包变量)"]
    end

    subgraph L3["第三层:包装器层"]
        W1["def wrapper(*args, **kwargs):"]
        W2["执行循环 n 次<br/>调用 func()"]
    end

    P1 -->|返回 decorator| P2
    P2 -.->|"n 被捕获"| D1
    D1 -->|返回 wrapper| D2
    D2 -.->|"func 被捕获"| W1
    W1 --> W2

    style L1 fill:#ffcdd2
    style L2 fill:#c8e6c9
    style L3 fill:#bbdefb

3. 多层装饰器链执行顺序

sequenceDiagram participant A as @A 外层 participant B as @B 中间 participant C as @C 内层 participant F as 原始函数 Note over A,F: 装饰阶段(定义时,从下到上) C->>C: 装饰 C B->>B: 装饰 B A->>A: 装饰 A Note over A,F: 调用阶段(从上到下,洋葱模型) A->>B: A 前置操作 B->>C: B 前置操作 C->>F: C 前置操作 F->>F: ★ 原始函数执行 ★ F-->>C: 返回结果 C-->>B: C 后置操作 B-->>A: B 后置操作 A-->>A: A 后置操作 Note over A: 最终结果
sequenceDiagram
    participant A as @A 外层
    participant B as @B 中间
    participant C as @C 内层
    participant F as 原始函数

    Note over A,F: 装饰阶段(定义时,从下到上)
    C->>C: 装饰 C
    B->>B: 装饰 B
    A->>A: 装饰 A

    Note over A,F: 调用阶段(从上到下,洋葱模型)
    A->>B: A 前置操作
    B->>C: B 前置操作
    C->>F: C 前置操作
    F->>F: ★ 原始函数执行 ★
    F-->>C: 返回结果
    C-->>B: C 后置操作
    B-->>A: B 后置操作
    A-->>A: A 后置操作

    Note over A: 最终结果

4. 类装饰器工作机制

flowchart TD subgraph Def["定义阶段"] DEF["@CallCounter<br/>def hello():"] INST["CallCounter(hello)<br/>→ 创建实例"] INST2["实例替换 hello<br/>hello 现在是 ClassCounter 实例"] end subgraph State["实例状态"] S1["self.func = hello"] S2["self.count = 0"] end subgraph Call["调用阶段"] C1["hello() 被调用"] C2["调用 __call__()"] C3["self.count += 1"] C4["调用 self.func()"] end DEF --> INST INST --> INST2 INST2 --> State State -.->|__call__| C2 C1 --> C2 C2 --> C3 C3 --> C4 style Def fill:#e3f2fd style State fill:#fff9c4 style Call fill:#e8f5e9
flowchart TD
    subgraph Def["定义阶段"]
        DEF["@CallCounter<br/>def hello():"]
        INST["CallCounter(hello)<br/>→ 创建实例"]
        INST2["实例替换 hello<br/>hello 现在是 ClassCounter 实例"]
    end

    subgraph State["实例状态"]
        S1["self.func = hello"]
        S2["self.count = 0"]
    end

    subgraph Call["调用阶段"]
        C1["hello() 被调用"]
        C2["调用 __call__()"]
        C3["self.count += 1"]
        C4["调用 self.func()"]
    end

    DEF --> INST
    INST --> INST2
    INST2 --> State
    State -.->|__call__| C2
    C1 --> C2
    C2 --> C3
    C3 --> C4

    style Def fill:#e3f2fd
    style State fill:#fff9c4
    style Call fill:#e8f5e9

5. 缓存装饰器工作原理

flowchart TD subgraph Input["输入"] ARGS["fibonacci(10)"] end subgraph Cache["缓存层 (memoize)"] CHECK{缓存中有<br/> (10) 吗?} HIT["✅ 命中<br/>返回缓存值"] MISS["❌ 未命中<br/>调用原始函数"] STORE["存储结果到缓存<br/>cache[(10)] = 55"] end subgraph Func["原始函数"] EXEC["执行 fibonacci(10)"] RESULT["返回 55"] end ARGS --> CHECK CHECK -->|有| HIT CHECK -->|没有| MISS MISS --> EXEC EXEC --> RESULT RESULT --> STORE STORE --> HIT HIT --> Output["输出: 55"] style Cache fill:#fff9c4 style Func fill:#c8e6c9 style HIT fill:#a5d6a7 style MISS fill:#ffcdd2
flowchart TD
    subgraph Input["输入"]
        ARGS["fibonacci(10)"]
    end

    subgraph Cache["缓存层 (memoize)"]
        CHECK{缓存中有<br/> (10) 吗?}
        HIT["✅ 命中<br/>返回缓存值"]
        MISS["❌ 未命中<br/>调用原始函数"]
        STORE["存储结果到缓存<br/>cache[(10)] = 55"]
    end

    subgraph Func["原始函数"]
        EXEC["执行 fibonacci(10)"]
        RESULT["返回 55"]
    end

    ARGS --> CHECK
    CHECK -->|有| HIT
    CHECK -->|没有| MISS
    MISS --> EXEC
    EXEC --> RESULT
    RESULT --> STORE
    STORE --> HIT
    HIT --> Output["输出: 55"]

    style Cache fill:#fff9c4
    style Func fill:#c8e6c9
    style HIT fill:#a5d6a7
    style MISS fill:#ffcdd2

6. 重试装饰器工作流

flowchart TD START["调用 func()"] --> TRY["尝试执行"] TRY --> SUCCESS{成功?} SUCCESS -->|是| RETURN["返回结果 ✅"] SUCCESS -->|否| CHECK_ATTEMPT{已达<br/>最大重试次数?} CHECK_ATTEMPT -->|是| RAISE["抛出异常 ❌"] CHECK_ATTEMPT -->|否| WAIT["等待 delay 秒"] WAIT --> ADJUST["delay × backoff<br/>(指数退避)"] ADJUST --> TRY style START fill:#e3f2fd style TRY fill:#fff3e0 style RETURN fill:#c8e6c9 style RAISE fill:#ffcdd2 style WAIT fill:#f3e5f5
flowchart TD
    START["调用 func()"] --> TRY["尝试执行"]
    TRY --> SUCCESS{成功?}
    SUCCESS -->|是| RETURN["返回结果 ✅"]
    SUCCESS -->|否| CHECK_ATTEMPT{已达<br/>最大重试次数?}
    CHECK_ATTEMPT -->|是| RAISE["抛出异常 ❌"]
    CHECK_ATTEMPT -->|否| WAIT["等待 delay 秒"]
    WAIT --> ADJUST["delay × backoff<br/>(指数退避)"]
    ADJUST --> TRY

    style START fill:#e3f2fd
    style TRY fill:#fff3e0
    style RETURN fill:#c8e6c9
    style RAISE fill:#ffcdd2
    style WAIT fill:#f3e5f5

7. 权限装饰器架构

flowchart TD subgraph Request["请求"] USER["用户对象<br/>{name, role, permissions}"] ACTION["要执行的操作"] end subgraph Auth["权限链"] AUTH_CHECK{已认证?} ROLE_CHECK{角色匹配?} PERM_CHECK{有权限?} end subgraph Execute["执行"] FUNC["执行操作"] LOG["记录审计日志"] end USER --> AUTH_CHECK AUTH_CHECK -->|否| DENY1["拒绝: 未认证"] AUTH_CHECK -->|是| ROLE_CHECK ROLE_CHECK -->|否| DENY2["拒绝: 角色不足"] ROLE_CHECK -->|是| PERM_CHECK PERM_CHECK -->|否| DENY3["拒绝: 权限不足"] PERM_CHECK -->|是| FUNC FUNC --> LOG style Request fill:#e3f2fd style Auth fill:#fff9c4 style Execute fill:#c8e6c9 style DENY1 fill:#ffcdd2 style DENY2 fill:#ffcdd2 style DENY3 fill:#ffcdd2
flowchart TD
    subgraph Request["请求"]
        USER["用户对象<br/>{name, role, permissions}"]
        ACTION["要执行的操作"]
    end

    subgraph Auth["权限链"]
        AUTH_CHECK{已认证?}
        ROLE_CHECK{角色匹配?}
        PERM_CHECK{有权限?}
    end

    subgraph Execute["执行"]
        FUNC["执行操作"]
        LOG["记录审计日志"]
    end

    USER --> AUTH_CHECK
    AUTH_CHECK -->|否| DENY1["拒绝: 未认证"]
    AUTH_CHECK -->|是| ROLE_CHECK
    ROLE_CHECK -->|否| DENY2["拒绝: 角色不足"]
    ROLE_CHECK -->|是| PERM_CHECK
    PERM_CHECK -->|否| DENY3["拒绝: 权限不足"]
    PERM_CHECK -->|是| FUNC
    FUNC --> LOG

    style Request fill:#e3f2fd
    style Auth fill:#fff9c4
    style Execute fill:#c8e6c9
    style DENY1 fill:#ffcdd2
    style DENY2 fill:#ffcdd2
    style DENY3 fill:#ffcdd2

8. 装饰器链组合全景

mindmap root((装饰器进阶)) 带参数装饰器 三层嵌套 可选参数 默认参数技巧 类装饰器 __call__ 方法 类状态管理 方法扩展 继承支持 实战 缓存 memoize LRU 缓存 TTL 缓存 重试 基础重试 指数退避 异常白名单 权限检查 角色检查 权限检查 认证授权 链式组合 洋葱模型 顺序依赖 关注点分离 装饰器工厂 陷阱 顺序依赖 返回值假设 副作用 性能影响
mindmap
  root((装饰器进阶))
    带参数装饰器
      三层嵌套
      可选参数
      默认参数技巧
    类装饰器
      __call__ 方法
      类状态管理
      方法扩展
      继承支持
    实战
      缓存 memoize
      LRU 缓存
      TTL 缓存
      重试
      基础重试
      指数退避
      异常白名单
      权限检查
      角色检查
      权限检查
      认证授权
    链式组合
      洋葱模型
      顺序依赖
      关注点分离
      装饰器工厂
    陷阱
      顺序依赖
      返回值假设
      副作用
      性能影响