欢迎光临
我们一直在努力

python:闭包(Closure)

一、什么是闭包?先用一句人话解释

闭包 = 函数 + 它创建时所捕获的外部变量

也可以理解为:

“带私有状态的函数”


二、一个最小但完整的闭包示例

def make_adder(x):
def adder(y):
return x + y
return adder

使用方式:

add_10 = make_adder(10)
print(add_10(5)) # 15
print(add_10(20)) # 30

发生了什么?

  • make_adder(10) 执行完后,本应销毁
  • 但 adder 记住了 x = 10
  • x 被“封”在函数里 —— 这就是 closure

📌 重点:
x 并不是参数,而是被“捕获”的变量


三、闭包 vs 普通函数

❌ 普通函数(无状态)

def add(x, y):
return x + y

  • 每次调用都要传全参数
  • 无法保存中间状态

✅ 闭包(有状态)

def make_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter

使用:

c = make_counter()
print(c()) # 1
print(c()) # 2
print(c()) # 3

👉 你得到了一个不依赖 class 的“对象”


四、闭包 ≈ 轻量级对象(非常重要)

我们用 class 对比一下:

class Counter:
def __init__(self):
self.count = 0

def next(self):
self.count += 1
return self.count

而闭包版本:

def make_counter():
count = 0
def next():
nonlocal count
count += 1
return count
return next

工程角度对比

对比项闭包class
语法复杂度
私有状态 天然支持 需要 self
适合 Agent / 回调 一般
适合复杂模型 一般

📌 这也是为什么 AI / LangChain 场景大量用闭包


五、一个经典工程示例:配置型函数

def make_logger(prefix):
def log(message):
print(f"[{prefix}] {message}")
return log

使用:

info = make_logger("INFO")
error = make_logger("ERROR")

info("service started")
error("db connection failed")

👉 不需要 class
👉 不需要全局变量
👉 每个 logger 都是“定制实例”


六、闭包在 Web / AI 中的真实用途

示例:构建一个 Agent(你刚写过的)

from typing import Callable

def build_agent() > Callable[[str], str]:
memory = []

def agent(prompt: str) > str:
memory.append(prompt)
return f"History size: {len(memory)}"

return agent

使用:

agent = build_agent()
print(agent("hi")) # History size: 1
print(agent("hello")) # History size: 2

🧠 这里的 agent 就是一个“带状态的函数对象”


七、Callable 是什么?为什么要引入?

先看这行代码:

def build_agent() > Callable[[str], str]:

它的含义是:

build_agent 返回一个函数
这个函数:

  • 接收 str
  • 返回 str

等价于 Java:

Function<String, String>


八、为什么闭包 + Callable 是绝配?

1️⃣ 没有 Callable 会怎样?

def build_agent():
...

  • IDE 无法提示
  • FastAPI 无法校验
  • 你不知道 agent 怎么用

2️⃣ 加上 Callable 后

def build_agent() > Callable[[str], str]:

你立刻知道:

  • 这是一个 agent
  • 输入输出是什么
  • 可以当作参数传递

📌 Callable = 闭包的“类型说明书”


九、再来几个经典闭包场景(速览)

1️⃣ 权限校验器(类似装饰器)

def require_role(role):
def check(user_role):
return user_role == role
return check


2️⃣ 延迟执行(lazy eval)

def lazy_sum(*nums):
def calc():
return sum(nums)
return calc


3️⃣ 策略模式(无 class)

def make_strategy(rate):
def apply(price):
return price * rate
return apply


十、什么时候该用闭包?什么时候不用?

✅ 适合用闭包

  • Agent / Tool
  • 回调函数
  • FastAPI 依赖注入
  • 状态简单、生命周期短

❌ 不适合用闭包

  • 复杂继承
  • 大量方法
  • 状态结构复杂

👉 那种场景用 class


十一、总结一句话

闭包让函数拥有“状态”,Callable 让函数拥有“类型”

在现代 Python(尤其是 AI / Web / 工程领域):

闭包 + Callable = 轻量级对象系统

赞(0)
未经允许不得转载:171主机测评 » python:闭包(Closure)
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址