Python之函数【三】(高阶函数和闭包)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

文章目录

  • 前言
  • 一、高阶函数
  • 二、闭包也称之为闭包函数
    • 1、浅谈闭包函数        
      • 1.1、划重点
      • 1.2、注意点
    • 2、怎么判断是不是闭包函数呢
      • 2.1、那接下来我们就细细的拆开解释
      • 2.2、对于这个作用域在JavaScript中的解释
      • 2.3、闭包函数的相关元素查看
        • ​​​​​​​​​​​​​​2.3.1、闭包函数的__code__属性编译后的函数定义体中保存着闭包函数的局部变量和自由变量的名称
        • 2.3.2、自由变量的值查看
  • 三、nonlocal关键字的使用​​​​​​​
  • 总结


前言

记录一下自己对高级函数和闭包函数的理解以及着重点和注意点的分析和讲解。这个章节的基础是为了理解装饰器。


一、高阶函数

什么叫高阶函数呢

定义如果一个函数的参数是另外一个或几个函数那么这个函数就是高阶函数。

怎么理解呢通俗点说就是一个函数中要传进来的参数就是一个函数。不是具体的字段值。

举例

 注意在这里在fun2函数里面要使用传进来的函数那么里面必须是一个函数的完整格式不能只是一个函数名称。

 

 当传入多个函数作为参数时

二、闭包也称之为闭包函数

1、浅谈闭包函数

闭包这个词有点怪其实就是一类具体一些明显特点的函数。也可以叫做闭包函数。

对于闭包我们先来讲闭包函数的三个特点。

1闭包函数内嵌套有其它函数

2内嵌函数引用了外层函数的变量

3外层函数的返回值是嵌套函数的函数名字

1.1、划重点

第一点闭包函数内嵌套有其它函数。也就是说定义了一个函数fun1那么在函数fun1中还可以定义一个函数fun2

第二点内嵌函数引用了外层函数的变量。也就是说在函数fun1中定义了一个变量a现在在函数fun2中引用了fun1的变量a。

第三点外层函数的返回值是嵌套函数的函数名字。也就是说fun1这个外层函数的返回值是fun2这个函数的名字。注意是名字。

 1.2、注意点

1如果要使用这种闭包函数那么就要先使用一个变量去接收这个函数的返回值。

2这个返回值就相当于是内层函数。

我们接下来细化理解一下

依据上面的例子a1去接收了fun1(这个函数的返回值。那么a1就等于fun2我们使用a1就等同于使用fun2()这个函数。

如果当函数fun1()里面传值但是fun2()里面不传值时调用函数的方式有些变化

2、怎么判断是不是闭包函数呢

 使用内层函数.__closure__方法来判断是否是闭包。如果返回的是一个cell对象那么就是闭包函数。如果返回None就不是闭包函数。

注意这里一定是内层函数去调用这个__closure__方法内层函数也就是外层函数的返回值。

总结我们可以看到闭包函数的一个特点就是嵌套函数。另一个特点是外层函数的变量作用域在内层函数中使用。

专业术语的定义是闭包是一种函数一种延伸了变量作用域的函数它会保留定义函数时变量的绑定当定义变量的作用域不可以用了那些绑定仍然可以被调用。

2.1、那接下来我们就细细的拆开解释

1闭包是一种函数。也就是说闭包是个名称全称闭包的名字也叫闭包函数。

2延伸了变量作用域的函数。也就是说本来变量的作用域在函数fun1现在把在函数fun1的变量拿到函数fun2中使用那么这种行为就叫做延伸了变量作用域。

3当定义变量的作用域不可以用了那些绑定仍然可以被调用。也就是说当函数fun1执行完毕了这里解释一下什么叫做执行完毕也就是说fun1运行完那么fun1的作用域也就跟着运行完。那么在函数fun2中使用函数fun1的变量这种关系是不会消除也就是说fun1函数运行完了我fun2函数还是能够照样使用你fun1的作用域对fun2函数产生不了影响。如果消除了那就不是闭包函数了。

通过对JavaScript语言对比的新解释那就是在一个函数里边再定义一个函数。这个内部函数一直保持有对外部函数中作用域的访问(小盒子可以一直访问大盒子但大盒子不能访问小盒子)。

对应第三点

我们类比学习不是闭包函数的作用域

 这里的作用域list_1只能在函数fun1中被应用。

2.2、对于这个作用域在JavaScript中的解释

 作用继承

所谓的作用域继承就像是儿子可以继承父亲的财产一样。比如我这里有一个大的盒子作为一个父级的作用域然后在这个大的盒子里边放一个小的盒子作为子作用域。我们规定可以在小盒子中获取到大盒子中的东西大盒子不能获取小盒子里的东西就称为作用域继承。

在 JS 中道理是一样的在一个函数里边我们再声明一个函数内部函数可以访问外部函数作用域的变量而外部的函数不能获取到内部函数的作用域变量。

参考博主文章闭包什么是闭包、闭包的作用、闭包的解决_BUG使我疯狂的博客-CSDN博客

2.3、闭包函数的相关元素查看

2.3.1、闭包函数的__code__属性编译后的函数定义体中保存着闭包函数的局部变量和自由变量的名称如下

co_varnames查看局部变量名称

co_freevars查看自由变量名称

顾名思义就知道这两个函数的意思了。

 2.3.2、自由变量的值查看

自由变量的值是保存在__closure__[freevars].cell_contents 属性中的

 

三、nonlocal关键字的使用

3.1、首先我们先明白一个场景。我们在一个普通函数中把局部变量变成全局变量使用的关键字是global。

 

3.2、那么在闭包函数里面可以使用global关键字的形式把局部变量改变成全局变量

答案是不行

1使用global关键字修改外层函数的变量

 

2使用nonlocal关键字修改外层函数的变量

 参考文章Python之闭包_python 装饰器_搬砖攒路费的博客-CSDN博客


总结

闭包函数一定满足三个特征但是满足这三个特征的函数不一定是闭包函数。因为里面的关键字申明的变量我们上面的例子就很好的解释这一点了。

说通俗一点人会吃饭但吃饭的不一定是人。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: python