当前位置: 首页 > news >正文

创新的网站建站/零售客户电商网站

创新的网站建站,零售客户电商网站,成都网站建设 培训班,房产网站建设方案的论文python是一门很常用的解释型语言,在日常使用中十分容易上手,但是实际上python中也有一些很高级很复杂的使用方式,学习这些方法对于理解整个python语言的构造、运行方式、以及提升学习者对python语言整体性的理解是很有必要的(实际上是因为我发…

在这里插入图片描述

python是一门很常用的解释型语言,在日常使用中十分容易上手,但是实际上python中也有一些很高级很复杂的使用方式,学习这些方法对于理解整个python语言的构造、运行方式、以及提升学习者对python语言整体性的理解是很有必要的(实际上是因为我发现有的时候我写的代码不按照我想的方式来运行,可能这些和python的某些特殊设计有关,因此我觉得有必要把python学得全面一点)。

本文主要从程序的动态作用域和静态作用域入手介绍一下python函数中会出现的闭包现象的使用方式。或许在当下可能用不太上,但是我觉得这些功能还是挺牛的,总会有用的上的时候(其实是因为不熟,不知道怎么方便地用到自己的工作中)。

文章目录

    • 动态作用域和静态作用域
    • python函数闭包


动态作用域和静态作用域

要解释闭包现象,我觉得首先可以理解一下静态作用域动态作用域两个概念。

作用域,是程序设计中的概念,作用域简单解释实际上就是某个被定义的函数或者变量能够在整个脚本中被访问的范围。为什么要说是能够呢,是因为某些被定义的函数或者变量是局限性的,只有在某些特定的代码片中才能访问,比如说在函数中定义的变量只有在调用函数的时候才能被访问到。

理解了作用域后,动态作用域和静态作用域就比较好理解了。其实动态作用域和静态作用域是相对的概念,静态作用域与其名相称,也就是函数的作用域在定义的时候就已经被决定了;而对于动态作用域来说,在不同的地方对某个函数进行调用会产生不同的作用域,也即函数调用时作用域才被决定。

只说的话实际上有点抽象,看个例子就知道啦!(我暂时只会写python,就用python举例子啦,但是要知道python只支持静态作用域!!!)

抬上例子:

# 例1# python函数,此处仅作为例子(python只支持静态作用域)a = 'nihao'def test1():print(a)def test2(func):a = 'hello'func()test2(test1)

上面这段代码在静态作用域和动态作用域中执行的结果是不同的。

上面这段代码在静态作用域中的执行结果是什么呢?结果是’nihao’,可能还有点懵是吧,我开始也有点懵,但是实际上这就是静态作用域的效果。怎么理解呢?实际上是因为 test1() 这个函数被定义后产生了其自身的作用域,test1()能访问到的只有全局变量和test1()内部的变量,也就是说在test2()函数中,被调用的test1()是访问不到test2()中定义的a变量的。也正是因此test2(test1)执行时test1()只能访问到全局的变量a,也就打印了"nihao"。

那么上面的例子如果在动态作用域中是怎样的呢?可能你已经猜到啦,应该是打印出"hello",这是因为在支持动态作用域的编程语言中,作用域随着我们使用函数的不同方式会发生变化 在这个例子中,要在test2()中调用test1函数,这时test1要执行的话能够访问到的作用域是test2()中定义的所有变量和所有全局变量,当然如果test1自身有定义变量,那么也能够访问到,这么多作用域它要获取哪里的a变量呢,就是调用test1时最接近test1函数的a变量,在这个例子中也就是test2中定义的a=“hello”。访问的顺序也就是从test1向调用test1的函数的外层一层一层进行访问,直到能得到一个a变量的值就停止。(这里我也验证不了,毕竟python使用的是静态作用域:(

当前大部分的编程语言都是只采用静态作用域的,比如C/C++、C#、Python、Java等等,支持动态作用域的编程语言只有极少数如Lisp、perl(两种作用域兼具)等。

python函数闭包

了解了动态作用域和静态作用域后,要理解闭包概念就比较容易了(参见例2的简易闭包)。实际上闭包现象存在于很多编程语言中,网上能查到最多的就是关于JavaScript的闭包的解释了。JavaScript MDN学习文档中关于闭包的解释是“一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域”。其实最重要的就是最后一句,闭包能让你在一个内层函数中访问到其外层函数的作用域,因为在正常情况下一个函数的作用域是不能被访问到的,函数的作用域只在函数内部。实际上闭包的本质可以归于静态作用域和万物皆对象的理论,为什么这么说呢,先看一下例子。

抬上例子:

# 例2def outer():   # 设置外函数f = 5def inner():   # 设置内函数print(f)   return inner    # 返回内函数给outer()a = outer()   # 将outer()的运行结果赋值给一个变量,此时的a是一个函数即inner
a()    # 实际上是在执行inner函数,同outer()()结果

或许你还不知道return inner是什么意思。首先,万物皆对象,python中的任何东西都是对象,也正是因此,对象才能够被以变量形式存储,也即我们可以任意的将函数或者变量进行分发给不同的变量名,但是实际上这些变量名背后都是最初的那个函数或者变量。也就是说这些函数或者变量名的在内存中的储存地址不会改变。我们调用这些不同的变量名实际上是调用的最初设置的对象(函数或者变量)。

现在进一步来理解上面的代码,return inner实际上就是将一个函数即inner返回给了outer()函数。之后将outer()函数的运行结果赋值给了a,注意a代表的是outer()的运行结果。而outer()的运行结果是什么呢,是inner这个函数名,也就是a = inner,那最后一步a()实际上就代表了inner()函数的运行结果,也正是因此上述代码的运行结果是5。可以看出在整个代码的运行中,不论函数如何调用,inner函数和outer函数的作用域都是确定的,也正是因此,静态作用域在此处发挥了功能。那么静态作用域是怎么发挥功能的呢,实际上就是内函数能够获取到外函数中的变量,这些被获取到的变量可以通过内函数被获取到(这里的例子就是打印出了外函数的f变量),这样的功能在获取局部变量时应该十分好用(毕竟我没用过,只能说应该)。

开始的时候我搞混了一个地方,先上例子:

# 例3# 和第一个例子相似,但对test1的调用方式不同。此处是把test1作为参数返回出来
a = 'nihao'def test1():print(a)def test2(func):a = 'hello'return functest2(test1)()

此段代码运行的结果还是"nihao",也就是test1部分被调用时并没有获取到test2里面的a变量。思考之后认为上面的例2之所以打印hello,应该是因为在外函数中定义内函数时才会使内函数获取到外函数的变量,也就是说定义的外函数outer建立起了自己的作用域,直到return语句结束后才结束,inner函数由于是在外函数内部定义,因此也属于outer的作用域。但是在例3中,test1函数处于外部,是被test2所调用的,也就是说test1函数并不在test2的作用域中,也正是因此test1获取不到test2中的a变量值

同时也能看出这里是静态作用域,因为test1和test2函数写好之后我们就能知道两个函数所具有的作用域了,要是这里是动态作用域的效果的话,test1直接访问离test1最近的a变量即test2提供的变量,那么打印的就是“hello”了(这里也侧面说明了代码中的test2(test1)()的运行对test1的调用并没有改变test1的作用域)。

现在应该大概理解了闭包的意思了吧。

除了上面获取函数变量的功能外,闭包还有一个作用就是内部函数会储存变量,也就是我们使用内函数访问到的外函数中的变量是不会从内存中清除的。正常来说函数在调用后其中的变量就不再被储存了,但是内函数所返回的变量值会继续保存在内存中直到外函数被清除。这里其实可以和之前的内容结合起来,即a = outer()其实是inner函数,再次执行a()是获取inner函数执行的结果,因此其执行并不经过外函数,从而能够储存之前获取到的变量。从整体上来看可以把内函数当做子函数,外函数为父函数,子函数能够访问父函数中的所有变量,同时子函数在父函数运行后还能够储存父函数的变量并使此变量变为全局变量。

上例子:

def outer():   # 设置外函数(父函数)f = 5w = 10l = [w]def inner():   # 设置内函数(子函数)nonlocal f   # 令f为非局部变量,即其改变会影响到全局l[0] += 1   # 使用列表等可变格式亦可设置非局部变量f += 1print("f的值",f)print("w的值",l[0])return inner    # 返回内函数给outer()a = outer()   # 将outer()的运行结果赋值给一个变量,此时的a是一个函数即inner
a()
a()
del a
a()

运行结果(这里不再解释啦):

在这里插入图片描述

总结一下,在python中构成闭包的两个条件:

  • 闭包含有内函数和外函数,外函数中必须返回一个函数对象(其实就是内函数)
  • 内函数中必须引用到外函数中的变量,否则若是外函数和内函数执行不相关的功能的话闭包就没意义了

参考了很多网上的资料才算大致理解,花了很多时间,感觉内容也是很丰富呀,希望以后能用上吧!哈哈。其实在python中闭包还是有用武之地的,比如装饰器的使用,下一篇文章想写一下装饰器的使用。

参考:谈谈自己的理解:python中闭包,闭包的实质
参考:https://www.zhihu.com/question/283708101
参考:https://www.zhihu.com/question/34210214
参考:静态作用域与动态作用域的区别
参考:闭包

http://www.jmfq.cn/news/5114377.html

相关文章:

  • 爬虫网站怎么做/广安百度推广代理商
  • 舟山市建设信息港网站/aso平台
  • 武汉做网站的大公司有哪些/网络营销毕业论文范文
  • 前台发布视频wordpress/baike seotl
  • 用php内容做电商网站/广告资源对接平台
  • 厦门网页设计培训班/seo优化排名价格
  • php网站开发自学/网店推广培训
  • 辽宁智能网站建设制作/上海网站外包
  • 靖江做网站哪家好/关键词林俊杰在线听免费
  • 移动端的网站/山东工艺美术学院网站建设公司
  • 用自建网站做外贸/seo网络优化招聘信息
  • 沈阳疫情最新消息今天新增病例/宁波品牌网站推广优化公司
  • 长沙网站开发设计/怎么开网店新手入门
  • 学网站建设难/百度软件
  • 网站建设培训合肥/哪里有做网络推广的
  • 昆明网站建设去出发科技公司/seo推广百度百科
  • 做办公设备网站/软文投稿平台有哪些
  • 新手做站必看 手把手教你做网站/邵阳疫情最新消息
  • 企业网站备案 淘宝客/微信广告平台推广
  • 做网站维护工资多少/semester
  • 网站建设工作情况汇报/霸屏seo服务
  • 岳阳建设银行网站/seo短视频网页入口引流免费
  • xmapp怎样做网站/交友平台
  • 四川成都网站优化/seo技术培训教程视频
  • 第三方做农产品价格数据的网站/外贸怎么找客户资源
  • 沈阳免费做网站/seo网站关键词优化哪家好
  • 深圳网站制作联系电话/百度系优化
  • 大连做网站软件/搜索关键词优化服务
  • 网站制作三站/网店运营培训
  • 长宁区网站制作/搜狗站长平台验证不了