资讯专栏INFORMATION COLUMN

python闭包探究一二

jzman / 2563人阅读

摘要:在嵌套函数中访问了最外层函数的参数,结果我们是能正常访问闭包我们将上面的最外层的返回值修改为返回嵌套函数的引用一切皆对象根据前面变量生存期例子,按理说调用完的生命周期应该结束了,调用应该失败才对,但是实际却调用成功了。

复习

python引用变量的顺序: 当前作用域局部变量 -> 外层作用域变量 -> 当前模块中的全局变量 -> python内置变量

global:声明一个全局变量

nonlocal:用来在函数或其他作用域中使用外层(非全局)变量

对于global跟nonlocal请点击 python3中global 和 nonlocal 的作用域

变量生存期

我们写个简单的变量生存期的小例子

def transmit_to_space(message):
    print(message)

print(transmit_to_space("Test message"))

print(message)  # 报错 NameError: name "message" is not defined 
嵌套函数

Python 允许函数中有函数,即为嵌套函数。

def transmit_to_space(message):
    "This is the enclosing function"
    def data_transmitter():
        "The nested function"
        print(message)

    data_transmitter()

print(transmit_to_space("Test message"))

在嵌套函数中访问了最外层函数的参数,结果我们是能正常访问 message

闭包

我们将上面的最外层(enclosing function) 的返回值修改为返回嵌套函数的引用(Python一切皆对象)

def transmit_to_space(message):
  "This is the enclosing function"
  def data_transmitter():
      "The nested function"
      print(message)
  return data_transmitter

fun2 = transmit_to_space("Burn the Sun!")
fun2()

根据前面变量生存期例子,按理说 transmit_to_space("Burn the Sun!") 调用完 message 的生命周期应该结束了,fun2调用应该失败才对,但是实际却调用成功了。

其实这里涉及到了闭包,我们查看 fun2 的 __closure__ 属性 (python2下是func_closure)。看到有一个cell对象,里面值就是 message 的内容。

所以闭包是: 嵌套定义在非全局作用域里面的函数能够记住它在被定义的时候它所处的封闭命名空间。(只会记住被嵌套函数使用的值,如果enclosing function 里面还定义了其他的值,封闭作用域里面是不会有的)

看下面例子的变化

我们增加一个参数,但是嵌套函数中未使用这个参数,发现fun2就没有再记住这个值。


更多链接:Python闭包详解

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

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

相关文章

  • [零基础学Python]一二三,集合了

    摘要:最简单的说法,即是在最原始的集合论朴素集合论中的定义,集合就是一堆东西。若然是集合的元素,记作。这里对被数学家们称为直观的或朴素的集合论进行一个简短而基本的介绍更详细的分析可见朴素集合论。对集合进行严格的公理推导可见公理化集合论。 回顾一下已经了解的数据类型:int/str/bool/list/dict/tuple 还真的不少了. 不过,python是一个发展的语言,没准以后还出别...

    CastlePeaK 评论0 收藏0
  • JS程序

    摘要:设计模式是以面向对象编程为基础的,的面向对象编程和传统的的面向对象编程有些差别,这让我一开始接触的时候感到十分痛苦,但是这只能靠自己慢慢积累慢慢思考。想继续了解设计模式必须要先搞懂面向对象编程,否则只会让你自己更痛苦。 JavaScript 中的构造函数 学习总结。知识只有分享才有存在的意义。 是时候替换你的 for 循环大法了~ 《小分享》JavaScript中数组的那些迭代方法~ ...

    melody_lql 评论0 收藏0
  • 前端进击的巨人(二):栈、堆、队列、内存空间

    摘要:中有三种数据结构栈堆队列。前端进击的巨人一执行上下文与执行栈,变量对象中解释执行栈时,举了一个乒乓球盒子的例子,来演示栈的存取方式,这里再举个栗子搭积木。对于基本类型,栈中存储的就是它自身的值,所以新内存空间存储的也是一个值。 面试经常遇到的深浅拷贝,事件轮询,函数调用栈,闭包等容易出错的题目,究其原因,都是跟JavaScript基础知识不牢固有关,下层地基没打好,上层就是豆腐渣工程,...

    edgardeng 评论0 收藏0
  • js下探究 let, var 之于闭包

    摘要:问题在说闭包,一定会牵涉到作用域。这也是闭包的属性的,能够记录下内部函数引用外部的值。因为都是全局变量,所以循环也就是不断值覆盖,闭包并不会记录在循环时的值,只会记录闭包变量。闭包时记录的除了闭包变量还有块级作用域变量最后来看看这个输出什么 js 是非常灵活的语言,写起来真是* 不过现在有了typescript,写起来舒服多了。 问题 在说js闭包,一定会牵涉到作用域。而一般在区别 v...

    BLUE 评论0 收藏0
  • javascript知识点

    摘要:模块化是随着前端技术的发展,前端代码爆炸式增长后,工程化所采取的必然措施。目前模块化的思想分为和。特别指出,事件不等同于异步,回调也不等同于异步。将会讨论安全的类型检测惰性载入函数冻结对象定时器等话题。 Vue.js 前后端同构方案之准备篇——代码优化 目前 Vue.js 的火爆不亚于当初的 React,本人对写代码有洁癖,代码也是艺术。此篇是准备篇,工欲善其事,必先利其器。我们先在代...

    Karrdy 评论0 收藏0

发表评论

0条评论

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