资讯专栏INFORMATION COLUMN

Python - 闭包Closure

Jason_Geng / 665人阅读

摘要:恩如期来啦闭包一函数作为返回值介绍闭包之前,先了解一下函数作为返回值的情况。例如之前介绍的装饰器中,就出现了将函数作为返回值。当执行时,相当于执行,且包含。允许使用关键字创造匿名函数。例如调用默认可以把匿名函数作为返回值返回,例如


恩~ 如期来啦“闭包”~


一、函数作为返回值

介绍“闭包”之前,先了解一下函数作为返回值的情况。
高阶函数除了可以接收函数作为参数外,还可以把函数作为结果值返回。例如之前介绍的装饰器中,就出现了将函数作为返回值。

二、闭包 1、产生闭包的条件以及作用

什么是闭包?
当在函数中嵌套另一个函数时,如果内部函数引用了外部函数的变量,则可能产生闭包。
所以闭包产生的三个条件(缺一不可)

1、必须嵌套一个内部函数

2、内部函数必须引用外部函数的变量

3、外部函数必须返回内部函数

那为什么要试用闭包,闭包的作用呢?

1、闭包可以根据外部函数的局部变量来得到不同的结果

2、当闭包执行完成后,仍可以保持当前的运行环境,执行结果依赖于该函数上一次的运行结果

2、闭包举例

栗子一:求序列之和

</>复制代码

  1. >>> def calc_sum(*args):
  2. ... ax = 0
  3. ... for n in args:
  4. ... ax = ax + n
  5. ... return ax # 返回变量
  6. ...
  7. >>> calc_sum(1,2,3)
  8. 6

但是,现在如果要求不需要立即取得求和结果,而是在后面的代码中,根据需要再计算,该怎么弄呢?
我们可以不返回求和的结果,而返回求和的函数,如下:

</>复制代码

  1. >>>def lazy_sum(*args):
  2. ... def sum(): # sum()是内部函数,可以利用外部函数的参数
  3. ... ax = 0
  4. ... for n in args: # sum()中使用外部函数的局部变量
  5. ... ax = ax + n
  6. ... return ax
  7. ... return sum # 形成闭包,此时,*args保存在返回的函数中
  8. ...
  9. >>>f = lazy_sum(1,3,5,7,9)
  10. >>>f # 此时返回的是求和函数
  11. >>> f() # 调用函数f()时,才真正计算求和的结果
  12. 25

注意:

lazy_sum()函数的内部执行顺序,执行f时,运行到return sum处,*args保存在返回函数中,返回的是sum()函数。当执行f()时,相当于执行sum(),且包含*args

当我们调用lazy_sun()时,每次都会返回一个新的函数,即使传入相同的参数,但是f()调用结果不影响。

我们来验证第二点:

</>复制代码

  1. # 但是调用 f1() 与f2()的调用结果互不影响
  2. >>> f1 = lazy_sum(1,3,5,7,9)
  3. >>> f2 = lazy_sum(1,3,5,7,9)
  4. >>> f1
  5. .sum at 0x013DD618>
  6. >>> f2
  7. .sum at 0x02F92DF8>
  8. >>> f1 == f2
  9. False
  10. >>> f1() == f2()
  11. True
  12. >>> f1()
  13. 25
  14. >>> f2()
  15. 25
  16. >>> id(f1())
  17. 1627215984
  18. >>> id(f2())
  19. 1627215984

说明:f1f2返回函数的位置不一样,所以f1==f2返回结果为False
但是不影响最后的执行结果,f1()f2()的执行结果均为25,且用id()进行查看,指向是同一块区域。

栗子二:

</>复制代码

  1. def count():
  2. fs = []
  3. for i in range(1, 4):
  4. def f(): # 返回函数f()放在循环里
  5. return i*i
  6. fs.append(f)
  7. return fs
  8. f1, f2, f3 = count()

实际执行结果为:f1=9 f2=9 f3=9
可能与实际想的([1,4,9])有点不一样。因为f()函数放在了for循环里,只有当循环结束后,最后才返回i=3的执行结果9。
所以返回函数最好不要引用任何循环变量,或者说后续可能变化的量。那如何来修改呢?

</>复制代码

  1. def count():
  2. def f(j):
  3. def g():
  4. return j*j # 形成闭包
  5. return g
  6. fs = []
  7. for i in range(1, 4):
  8. fs.append(f(i)) # 一个i值进入后,f(i)立刻被执行,并加入到fs中
  9. return fs
  10. f1, f2, f3 = count() # 返回函数g没有引用j

最后结果:[1,4,9] 即f1=1 f2=4 f3=9


三、匿名函数lambda

定义:匿名函数指一类无需定义标识符函数名的函数或者子程序。Python允许使用lambda关键字创造匿名函数。

语法lambda 参数:表达式
或者 lambda 形参1,…,形参n : function(形参),入参1,…,入参n

注意:1、lambda函数可以接收任意多个参数并且返回单个表达式的值;
2、lambda中不能包含命令,返回的表达式不能超过一个。

优点:1、可以省去定义函数的过程,精简代码;
2、对于一些抽象的、不会重复使用的函数可以用lambda进行定义。

例子:

</>复制代码

  1. >>> list( map( lambda x: x*x ,[1,2,3] ) )
  2. [1, 4, 9]

其中lamdba x : x*x 实现的是:def f(x): return x*x 的功能。

可以把匿名函数赋值给一个变量,再利用变量调用该函数。例如:

</>复制代码

  1. >>> f = lambda x:x*x
  2. >>> f(5) # 调用
  3. >>> g = lambda x,y=2 : x*y
  4. >>> g(2,4)
  5. 8
  6. >>> g(2) # 默认y=2
  7. 4

可以把匿名函数作为返回值返回,例如:

</>复制代码

  1. return lambda x:x*x

❤ thanks for watching, keep on updating...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/42474.html

相关文章

  • 说说Python中的闭包 - Closure

    摘要:闭包可以用来在一个函数与一组私有变量之间创建关联关系。夹带私货外部变量返回的是函数,带私货的函数支持将函数当成对象使用的编程语言,一般都支持闭包。所以说当你的装饰器需要自定义参数时,一般都会形成闭包。 Python中的闭包不是一个一说就能明白的概念,但是随着你往学习的深入,无论如何你都需要去了解这么一个东西。 闭包的概念 我们尝试从概念上去理解一下闭包。 在一些语言中,在函数中可以(嵌...

    leon 评论0 收藏0
  • PyTips 0x04 - Python 闭包与作用域

    摘要:项目地址闭包在计算机科学中,闭包英语,又称词法闭包或函数闭包,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。 项目地址:https://git.io/pytips 闭包(Closure) 在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是...

    leejan97 评论0 收藏0
  • python基础知识之函数初阶——闭包

    摘要:我们说触发了闭包的函数叫做闭包函数闭包最大的特点就是它可以被外层函数返回后赋值给一个变量,并且携带了外层函数内定义的变量例子如下变量为函数开辟的局部命名空间内定义的变量函数内引用了变量的内层函数名被当作返回值,此时闭包规则达成。 什么是闭包? 其实我们在使用函数过程中不经意间就会触发闭包,因为总会出于某种原因会在函数内引用或修改上一层函数的变量,这时就会触发闭包 那么什么是闭包?其实就...

    TIGERB 评论0 收藏0
  • Python Closure

    摘要:在计算机科学中,闭包又称词法闭包或函数闭包,是引用了自由变量的函数。闭包被广泛应用于函数式语言中。运用闭包可以避免对全局变量的使用。将栈顶的元素取出,创建元组,并将该元组进栈。 在计算机科学中,闭包 又称 词法闭包 或 函数闭包,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。闭包被广泛应用于函数式语言中。 从上面这段话中可以看出闭...

    n7then 评论0 收藏0
  • Python 自定义函数的特殊属性(收藏专用)

    Python 中通过函数定义所创建的用户自定义函数对象均具有一些特殊属性,需要注意的是这里介绍的是自定义函数(function类型)的特殊属性,而非方法(method 类型)的特殊属性,函数和方法的特熟属性以及默认的返回值可能不尽相同。 对于大多数特殊属性,可以通过下面这个例子示范一下: class Test(): def func(self, v = dog): 这里演...

    zhou_you 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<