Python闭包是什么及怎么使用


这篇文章主要介绍“Python闭包是什么及怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python闭包是什么及怎么使用”文章能帮助大家解决问题。计算机中有些英文专业词汇,字面直译,难免因缺少上下文而显得苍白拗口,须得多方铺垫,方能味得古怪下面的原理。闭包(closure)便是一个这样牵扯了许多上下文的概念,包括编程语言最基本的绑定(binding),环境(environments),变量作用域(scope)以及函数是第一等公民(function as the first-class)等等。在Python中,binding(绑定) 是编程语言最基本的抽象手法,它将一个值绑定到一个变量上,并且稍后可以引用或者修改该变量。下面是几种不同层次的绑定,每组语句在运行时将一个名字与对应值绑定到其定义所在的环境中。依照执行顺序,同名多次绑定,后面会覆盖前面:说这些都是抽象,是因为它们提供了对数据、复合操作或数据集合的封装手段,即将一个名称与复杂的数据或逻辑进行捆绑,使调用者不用关心其实现细节,并可以据此来构建更复杂的工程。可以说绑定是编程的基石。回到本文的主题上来,闭包是对一组复合语句的抽象,也就是函数,只不过是一种特殊的函数,至于这个特殊性在哪,这里先卖个关子,等稍后引入更多概念后再进行阐述。scope(作用域),顾名思义,也就是某个binding 能罩多大的范围,或者说可以在多大范围内访问的到一个变量。每个函数定义会生成一个局部定义域。Python,和大多数编程语言一样,使用的是静态作用域(static scoping,有时也称 lexical scoping)规则。在函数嵌套定义的时候,内层函数内可以访问外层函数的变量值。因此你可以把作用域想象成一个容器,即它是可以嵌套的,并且内层作用域会扩展外层作用域,而最外层作用域即全局作用域。上一小节提到了,多次同名绑定,后面会覆盖先前,其实有隐含前提:在同一作用域内。如果是嵌套作用域,其实是隐藏的关系,内层函数的变量定义会遮蔽外层函数同一名字定义,但是在外层作用域中,该变量仍是原值:作用域其实也可以从另一个角度理解,即我们在某个环境(environment)中,在确定一个name binding 值的时候,会从最内层作用域顺着往外找,找到的第一个该名字 binding 的对应的值即为该 name 引用到的值。需要强调的时候,函数的嵌套定义会引起定义域的嵌套,或者说环境扩展(内层扩展外层)关系。类的定义又稍有不同,class 定义会引入新的namespace(命名空间),命名空间和作用域是常拿来对比的概念,但这里按下不表,感兴趣的可以自己去查查资料。说到这里,要提一下,一个常被说起的反直觉例子:想象中,上面print处应该输出 4 或者 5 才对,为什么会报错呢?这是因为test函数在被解释器解析的时候,分词器会扫一遍 test 函数定义中的所有 token(符号),看到赋值语句a=5的存在,就会明确a是一个局部变量,因此不会输出 4。而在执行到print(a)的时候,在局部环境中,a还未被binding,因此会报UnboundLocalError。稍微扩展说明一下,虽然 Python 是解释执行的,即输入一句,解释一句,执行一句。但是对于代码块(即头部语句,冒号与其关联的缩进块所构成的复合语句(compound sentences),常见的有函数定义,类定义,循环语句等等)来说,还是会整体先扫一遍的。一般来说,组成编程语言的元素,如变量、函数和类,会被设定不同的限制,而具有最少限制的元素,被我们称为该编程语言中的一等公民。而一等公民最常见的特权有:套用到 Python 中的函数,即一个函数可以被赋值给某个变量,可以被其他函数接收和返回,可以定义在其他函数中(即嵌套定义):并不是在所有语言中,函数都是一等公民,比如 Java8 以前的 Java,上面四项权利 Java7 中的函数后几项都没有。使用函数作为第一等公民的做法,我们成为函数式编程。在这个大数据时代,由于对并发的友好性,传统过程式语言(比如 Cpp、Java)都在新版本上逐渐支持函数式编程范式。在这里,能够操作其他函数的函数(即以其他函数作为参数或者返回值的函数),叫做高阶函数。高阶函数使得语言的表达能力大大增强,但同时,也增加了编程复杂度。每个函数调用,会在环境中产生一个frame栈帧),并且在栈帧中会进行一些绑定,然后压入函数调用栈中。在函数调用结束时,栈帧会被弹出,其中所进行的绑定也被解除,即垃圾回收,对应的局部作用域也随之消亡。即在调用结束后,局部定义的变量 x在外边是访问不到的。但是如之前例子中,返回的add函数却引用了已经调用结束的add_num中的变量a,怎么解释这种现象呢?可以记住一条,也是之前提到过的:因此在外部函数返回后,返回的内部函数依然维持了其定义时的扩展环境,也可以理解为由于内部函数引用的存在,外部函数的环境中所有的绑定并没有被回收。千呼万唤始出来,以为是高潮,其实已结束。闭包就是建立在前面的这些概念上的,上面提到的某个例子:其实就是闭包。捡起之 香港云主机前伏笔,给出我对闭包的一个理解:它是一种高阶函数,并且外层函数(例子中的add_num)将其内部定义的函数(add)作为返回值返回,同时由于返回的内层函数扩展了外层函数的环境,也就是对其产生了一个引用,那么在调用返回的内部函数(add5)的时候,能够引用到其(add)定义时的外部环境(在例子中,即a的值)。关于“Python闭包是什么及怎么使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注开发云行业资讯频道,小编每天都会为大家更新不同的知识点。

相关推荐: POST、DELETE、PUT方法该如何使用

这期内容当中小编将会给大家带来有关POST、DELETE、PUT方法该如何使用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。熟悉RESTful风格的朋友,应该了解RESTful风格API使用HTTP method表达对资源的…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 11/12 20:47
下一篇 11/12 20:47

相关推荐