前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python的闭包(Closure)与惰性计算(Lazy Evaluation)

Python的闭包(Closure)与惰性计算(Lazy Evaluation)

作者头像
Steve Wang
发布2018-02-05 17:44:32
1.4K0
发布2018-02-05 17:44:32
举报
文章被收录于专栏:从流域到海域从流域到海域
闭包

在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。运行时,一旦外部的 函数被执行,一个闭包就形成了,闭包中包含了内部函数的代码,以及所需外部函数中的变量的引用。其中所引用的变量称作上值(upvalue)。 https://zh.wikipedia.org/wiki/%E9%97%AD%E5%8C%85_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6)(https://zh.wikipedia.org/wiki/%E9%97%AD%E5%8C%85_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6%29)

事实上,你可能在JavaScript那里看到过闭包,闭包在JavaScript是非常重要的常见高级特性。

我们可以来复习一下:

https://cloud.tencent.com/developer/article/1037126

惰性计算

讲Python惰性序列时,讲到过惰性计算,在来复习一下:

https://cloud.tencent.com/developer/article/1037320

Python中的闭包与惰性计算

闭包的基础是,语言层面要允许函数嵌套,即一个函数体里可以再包含了另一个一个函数,并且允许将函数作为返回值返回出去(这点也说明支持闭包的语言中,函数是对象的一种)。Python具备这些性质,因此也是支持闭包的语言。

闭包在Python中的使用和JavaScript不同,闭包在Python中的出现强调延迟得到结果,这点与惰性计算的特点相契合。

示例:

代码语言:javascript
复制
>>> def lazy_sum(*args):  #可变参数标准写法 前面的博客提到过
...     def sum():
...             res = 0
...             for i in args:
...                     res = res + i
...             return res
...     return sum
...
>>> lazy_sum(1, 2, 3, 4, 5)   #返回值是函数
<function lazy_sum.<locals>.sum at 0x04106198>
>>> func = lazy_sum(1, 2, 3, 4, 5)
>>> func()  #调用函数func时 lazy_sum()才真正执行
15
>>>
#闭包结构:
#内部函数sum引用了外部函数lazy_sum的参数和局部变量
#lazy_sum以函数sum作为返回值
#返回时,相关参数和变量都存储在sum中 
需要注意的地方
  • 每次调用lazy_sum, 返回的是一个不同的sum对象
  • 多次调用lazy_sum,上次调用的结果不会影响下一次
  • 返回函数不要引用值会发生改变的变量
代码语言:javascript
复制
#!usr/bin/env python3
# _*_coding: utf-8 _*_
def count1():
    fs = []
    for i in range(1, 4):    #i是闭包结构中的变量,被count1中的fs所引用 
        def f():
            return i * i
        fs.append(f)
    return fs

f1, f2, f3 = count1()

print(f1())
print(f2())
print(f3())
#结果
9
9
9
#由于惰性计算的原因 for循环执行完毕i等于3的时候 f才执行 务必注意闭包函数的执行时机
#解决方法 将for循环和square函数分隔开 并将循环变量做为参数传入
def count2():
    def f(j):
        def g():
            return j * j
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f(i))  #f(i)被立即执行 所以当前值被传入了f()
    return fs

f4, f5, f6 = count2()

print(f4())
print(f5())
print(f6())
#结果
1
4
9

以上例子来自廖雪峰的Python教程,原帖是介绍函数作为返回值的:

https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431835236741e42daf5af6514f1a8917b8aaadff31bf000#0

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年12月19日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 闭包
  • 惰性计算
  • Python中的闭包与惰性计算
    • 需要注意的地方
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档