千家信息网

如何使用闭包方法

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,本篇内容介绍了"如何使用闭包方法"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是 Python
千家信息网最后更新 2026年11月01日如何使用闭包方法

本篇内容介绍了"如何使用闭包方法"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

什么是 Python 闭包?

首先,让我使用一个简单的示例来说明什么是 Python 中的闭包。看下面的函数:

def outer():     x = 1     def inner():         print(f'x in outer function: {x}')     return inner

在一个函数内部定义另外一个函数,并返回这个函数,这种特性就是闭包。检查 outer 函数的返回值,可以确认这是一个函数。

>>> def outer(): ...     x = 1 ...     def inner(): ...         print(f'x in outer function: {x}') ...     return inner ... >>> outer  >>> outer() .inner at 0x7fb2ecdaca60> >>>

闭包这种特性能做什么呢?因为函数返回的是一个函数,我们就可以调用这个函数,比如:

>>> outer()() x in outer function: 1 >>>

不过我们一般会这么使用闭包,这样太丑陋了。你可能会好奇这个跟递归有什么关系?别着急,让我们慢慢体会闭包的牛逼之处。

闭包内的变量访问

从前述的运行结果来看,inner 函数可以访问 outer 函数内部定义的变量 x,但是却无法修改它,下面的代码运行时会报错:

>>> def outer(): ...     x = 1 ...     def inner(): ...         print(f'x in outer function (before modifying): {x}') ...         x += 1 ...         print(f'x in outer function (after modifying): {x}') ...     return inner ... >>> f = outer() >>> f() Traceback (most recent call last):   File "", line 1, in    File "", line 4, in inner UnboundLocalError: local variable 'x' referenced before assignment >>>

为了解决这个问题,我们可以加上 nonlocal 关键字,告诉 inner 函数,这不是一个本地变量:

>>> def outer(): ...     x = 1 ...     def inner(): ...         nonlocal x ...         print(f'x in outer function (before modifying): {x}') ...         x += 1 ...         print(f'x in outer function (after modifying): {x}') ...     return inner ... >>> >>> f = outer() >>> f() x in outer function (before modifying): 1 x in outer function (after modifying): 2 >>> f() x in outer function (before modifying): 2 x in outer function (after modifying): 3 >>> f() x in outer function (before modifying): 3 x in outer function (after modifying): 4 >>>

有没有发现,x 的值竟然被保存了下来,每次调用一下,就增加了 1,这就是闭包的妙处。

用闭包来替换递归

利用上述闭包会保留调用结果的特性,我们可以用这个来替换递归,比如利用闭包计算斐波那契数列:

def fib():     x1 = 0     x2 = 1     def get_next_number():         nonlocal x1, x2         x3 = x1 + x2         x1, x2 = x2, x3         return x3     return get_next_number

可以这样调用来生产斐波那契数列:

>>> def fib(): ...     x1 = 0 ...     x2 = 1 ...     def get_next_number(): ...         nonlocal x1, x2 ...         x3 = x1 + x2 ...         x1, x2 = x2, x3 ...         return x3 ...     return get_next_number ... >>> fibonacci = fib() >>> for i in range(2, 21): ...     num = fibonacci() ...     print(f'The {i}th Fibonacci number is {num}') ... The 2th Fibonacci number is 1 The 3th Fibonacci number is 2 The 4th Fibonacci number is 3 The 5th Fibonacci number is 5 The 6th Fibonacci number is 8 The 7th Fibonacci number is 13 The 8th Fibonacci number is 21 The 9th Fibonacci number is 34 The 10th Fibonacci number is 55 The 11th Fibonacci number is 89 The 12th Fibonacci number is 144 The 13th Fibonacci number is 233 The 14th Fibonacci number is 377 The 15th Fibonacci number is 610 The 16th Fibonacci number is 987 The 17th Fibonacci number is 1597 The 18th Fibonacci number is 2584 The 19th Fibonacci number is 4181 The 20th Fibonacci number is 6765 >>>

而使用递归方法计算斐波那契数列的方法如下所示:

def fib_recursion(n:int) -> int:     if n <= 1:         return n     return fib_recursion(n-1) + fib_recursion(n-2)

把之前的闭包版本封装一下:

def fib():     x1 = 0     x2 = 1     def get_next_number():         nonlocal x1, x2         x3 = x1 + x2         x1, x2 = x2, x3         return x3     return get_next_number  def fib_closure(n):     f = fib()     for i in range(2, n+1):         num = f()     return num

这样使用 fib_closure(20) 就可以计算出结果:

In [4]: fib_closure(20) Out[4]: 6765  In [5]: fib_recursion(20) Out[5]: 6765  In [6]:

现在使用 IPython 来测试下这两者的性能:

In [6]: %time fib_closure(20) CPU times: user 10 µs, sys: 1e+03 ns, total: 11 µs Wall time: 14.1 µs Out[6]: 6765  In [7]: %time fib_recursion(20) CPU times: user 2.76 ms, sys: 15 µs, total: 2.78 ms Wall time: 2.8 ms Out[7]: 6765

可以看出两差相差近 1000 倍,这还只是计算到第 20 个数的情况下,如果计算到 100,那使用递归会计算很久甚至无法计算出来。

闭包的其他用处

Python 的闭包不仅仅用于替换递归,还有很多场景可以使用闭包。比如学生成绩的分类函数:

学生成绩数据:

students = {     'Alice': 98,     'Bob': 67,     'Chris': 85,     'David': 75,     'Ella': 54,     'Fiona': 35,     'Grace': 69 }

现在需要根据学生成绩进行分类,通常情况下我们会写多个函数来进行分类,而分类的标准又会经常变化,这时候闭包就很方便了:

def make_student_classifier(lower_bound, upper_bound):     def classify_student(exam_dict):         return {k:v for (k,v) in exam_dict.items() if lower_bound <= v < upper_bound}     return classify_student  grade_A = make_student_classifier(80, 100) grade_B = make_student_classifier(70, 80) grade_C = make_student_classifier(50, 70) grade_D = make_student_classifier(0, 50)

如果分类标准变化,直接个性函数的参数即可,主要代码逻辑不变,如果想查找成绩分类为 A 的学生,只需要调用 grade_A(students) 即可:

In [13]: grade_A(students) Out[13]: {'Alice': 98, 'Chris': 85}

闭包使用上述分类函数很容易修改且更加易读。

"如何使用闭包方法"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

闭包 函数 分类 递归 方法 学生 成绩 变量 情况 数列 特性 结果 代码 内容 就是 更多 标准 知识 面的 变化 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技工作委员会主任 互联网的科技 科技股互联网 科技与互联网 科技互联网政务服务 金融科技与互联网金融 卓越科技互联网 招聘 富国互联网科技创新基金 天速互联网络科技有限公司 广州优美互联网科技 互联网教育科技公司vipkid 北京华百购互联网科技有限公司 昭通云南众福互联网科技有限公司 金融科技与互联网金融相同和不同 重庆互联网医院沙龙医盟信息科技 互联网科技商业 杭州壁岐互联网科技有限公司 深圳市罗太互联网科技有限公司 美国互联网科技公司 科技和互联网行业的特点 百单网互联网科技有限公司 互联网科技产业 互联网科技工作委员会主任 互联网最新的科技有限公司 与互联网科技公司 互联网汽车科技小镇 佳云科技和互联网广告 荆州市昕露互联网络科技有限公司 吉林省码上互联网科技电话 互联网科技企业商标注意事项
0