什么是python中的一等函数和闭包

一等函数(First-class Functions)

在 Python 里,函数就是对象,和整数、字符串一样能被:

• 赋值给变量

• 作为参数传入

• 作为返回值返回

• 放进列表/字典等数据结构

bash 复制代码
def apply_twice(f, x):
    return f(f(x))               # 函数当参数

inc = lambda v: v + 1            # 赋值给变量
print(apply_twice(inc, 3))       # 5

有了"一等函数",才有高阶函数、装饰器等强大抽象。

闭包(Closure)

定义:内层函数记住并携带了其外层作用域的变量(自由变量),即使外层函数已经返回,仍可使用这些变量。

满足三件事就是闭包:

  1. 有内层函数;2) 内层函数用到了外层的局部变量;3) 外层函数已经返回。
bash 复制代码
def make_adder(n):
    def add(x):
        return x + n             # 用到外层变量 n
    return add                   # 返回内层函数(形成闭包)

add5 = make_adder(5)
print(add5(10))                  # 15
print(add5.__closure__[0].cell_contents)  # 5(看看捕获的值)

修改外层变量:nonlocal

闭包里如需重新绑定外层局部变量,用 nonlocal(全局用 global)。

bash 复制代码
def counter():
    c = 0
    def inc():
        nonlocal c
        c += 1
        return c
    return inc

inc = counter()
print(inc(), inc(), inc())       # 1 2 3

经典坑:循环里的"晚绑定"(late binding)

闭包捕获的是变量引用,不是当时的值:

bash 复制代码
funcs = [lambda: i for i in range(3)]
print([f() for f in funcs])      # [2, 2, 2]  全都变成最后的 i

修法(任选其一):

bash 复制代码
# 1) 默认参数"定格"当前值
funcs = [lambda i=i: i for i in range(3)]

# 2) 再包一层工厂函数
funcs = []
for i in range(3):
    def make(j):
        return lambda: j
    funcs.append(make(i))

# 3) functools.partial
from functools import partial
def identity(x): return x
funcs = [partial(identity, i) for i in range(3)]

装饰器其实就是闭包

bash 复制代码
import time

def timing(fn):                  # 外层工厂,捕获 fn
    def wrapper(*args, **kwargs):
        t0 = time.perf_counter()
        try:
            return fn(*args, **kwargs)
        finally:
            dt = time.perf_counter() - t0
            print(f"{fn.__name__} took {dt:.3f}s")
    return wrapper

@timing
def work(n): 
    sum(range(n))

work(1000000)                    # 自动打印耗时

小结

• 一等函数:函数是"值",能传来传去。

• 闭包:函数能"带着环境里的变量一起走"。

配合 nonlocal 可更新状态;注意循环晚绑定,用"默认参数/工厂函数/partial"规避。

这些机制是 Python 中高阶抽象、装饰器、回调、工厂函数的基石。

相关推荐
卡提西亚12 小时前
C++笔记-24-文件读写操作
开发语言·c++·笔记
snakecy12 小时前
树莓派学习资料共享
大数据·开发语言·学习·系统架构
我的xiaodoujiao13 小时前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 24--数据驱动--参数化处理 Excel 文件 1
python·学习·测试工具·pytest
Nebula_g13 小时前
C语言应用实例:学生管理系统1(指针、结构体综合应用,动态内存分配)
c语言·开发语言·学习·算法·基础
开心-开心急了13 小时前
关于Flutter与Qt for python 的一些技术、开源、商用等问题
开发语言·python·qt·flutter
友友马13 小时前
『 QT 』按钮类控件属性解析
开发语言·数据库·qt
Evand J13 小时前
【MATLAB例程】基于噪声协方差自适应的互补滤波器方法vs标准互补滤波,用于融合加速度计和陀螺仪数据,估计角度
开发语言·matlab
熊小猿13 小时前
RabbitMQ死信交换机与延迟队列:原理、实现与最佳实践
开发语言·后端·ruby
@小码农13 小时前
2025年北京海淀区中小学生信息学竞赛第一赛段试题(附答案)
人工智能·python·算法·蓝桥杯
2301_7951672013 小时前
玩转Rust高级应用 如何让让运算符支持自定义类型,通过运算符重载的方式是针对自定义类型吗?
开发语言·后端·算法·安全·rust