美文网首页Python
2018-01-24 Python闭包的概念

2018-01-24 Python闭包的概念

作者: 大川无敌 | 来源:发表于2018-01-24 16:17 被阅读8次

作用域

作用域是程序运行时变量可被访问的范围,定义在函数内的变量是局部变量,局部变量的作用范围只能是函数内部范围内,它不能在函数外引用。

定义在模块最外层的变量是全局变量,它是全局范围内可见的,当然在函数里面也可以读取到全局变量的。例如:

num = 10 # 全局作用域变量
def foo():
print(num) # 10
而在函数外部则不可以访问局部变量。例如:

def foo():
num = 10
print(num) # NameError: name 'num' is not defined
嵌套函数

函数不仅可以定义在模块的最外层,还可以定义在另外一个函数的内部,像这种定义在函数里面的函数称之为嵌套函数(nested function)例如:

def print_msg():
# print_msg 是外围函数
msg = "zen of python"

def printer():
    # printer是嵌套函数
    print(msg)
printer()

输出 zen of python

print_msg()
对于嵌套函数,它可以访问到其外层作用域中声明的非局部(non-local)变量,比如代码示例中的变量 msg 可以被嵌套函数 printer 正常访问。

那么有没有一种可能即使脱离了函数本身的作用范围,局部变量还可以被访问得到呢?答案是闭包

什么是闭包

函数身为第一类对象,它可以作为函数的返回值返回,现在我们来考虑如下的例子:

def print_msg():
# print_msg 是外围函数
msg = "zen of python"
def printer():
# printer 是嵌套函数
print(msg)
return printer

another = print_msg()

输出 zen of python

another()
这段代码和前面例子的效果完全一样,同样输出 "zen of python"。不同的地方在于内部函数 printer 直接作为返回值返回了。

一般情况下,函数中的局部变量仅在函数的执行期间可用,一旦 print_msg() 执行过后,我们会认为 msg变量将不再可用。然而,在这里我们发现 print_msg 执行完之后,在调用 another 的时候 msg 变量的值正常输出了,这就是闭包的作用,闭包使得局部变量在函数外被访问成为可能。

看完这个例子,我们再来定义闭包,维基百科上的解释是:

在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。

这里的 another 就是一个闭包,闭包本质上是一个函数,它有两部分组成,printer 函数和变量 msg。闭包使得这些变量的值始终保存在内存中。

闭包,顾名思义,就是一个封闭的包裹,里面包裹着自由变量,就像在类里面定义的属性值一样,自由变量的可见范围随同包裹,哪里可以访问到这个包裹,哪里就可以访问到这个自由变量。

为什么要使用闭包

闭包避免了使用全局变量,此外,闭包允许将函数与其所操作的某些数据(环境)关连起来。这一点与面向对象编程是非常类似的,在面对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。

一般来说,当对象中只有一个方法时,这时使用闭包是更好的选择。来看一个例子:

def adder(x):
def wrapper(y):
return x + y
return wrapper

adder5 = adder(5)

输出 15

adder5(10)

输出 11

adder5(6)
这比用类来实现更优雅,此外装饰器也是基于闭包的一中应用场景。

所有函数都有一个 closure属性,如果这个函数是一个闭包的话,那么它返回的是一个由 cell 对象 组成的元组对象。cell 对象的cell_contents 属性就是闭包中的自由变量。

adder.closure
adder5.closure
(<cell at 0x103075910: int object at 0x7fd251604518>,)
adder5.closure[0].cell_contents
5
这解释了为什么局部变量脱离函数之后,还可以在函数之外被访问的原因的,因为它存储在了闭包的 cell_contents中了。

相关文章

  • 2018-01-24 Python闭包的概念

    作用域 作用域是程序运行时变量可被访问的范围,定义在函数内的变量是局部变量,局部变量的作用范围只能是函数内部范围内...

  • 彻底理解JS闭包

    闭包并不是JS所独有的,在计算机科学中其是一个普遍的概念,在Python中也有闭包的概念,但闭包在Python应用...

  • python函数之闭包

    目录 python函数之闭包什么是闭包python中的namespace闭包的条件闭包的优点 python函数之闭...

  • python闭包学习

    参考文章 python闭包python闭包一步一步教你认识Python闭包深入浅出python闭包

  • go语言学习(11)--闭包与函数式编程

    闭包 通过一个累加器来看闭包的概念 python 闭包 fun1返回的不是一个值,而是一个函数 fun2,a = ...

  • Python 闭包使用注意点

    1 Python 闭包 今天,聊下 python 的闭包。在函数编程中经常用到闭包。 闭包是什么,它是怎么产生的及...

  • 理解Python闭包概念,Python作用域详述!

    闭包并不只是一个python中的概念,在函数式编程语言中应用较为广泛。理解python中的闭包一方面是能够正确的使...

  • python闭包详解

    (一)了解python装饰器之前我们可以先了解什么闭包 闭包概念:在一个内部函数中,对外部作用域的变量进行引用,(...

  • Python学习笔记(十一)闭包

    本文主要介绍python中的闭包(closure) 闭包的概念 如果在一个函数的内部定义了另外一个函数,外部的函数...

  • Swift笔记・闭包(一)

    阅读Swift中文文档所做笔记 闭包的简单概念 闭包是可以在你的代码中被传递和引用的功能性独立模块,和Python...

网友评论

    本文标题:2018-01-24 Python闭包的概念

    本文链接:https://www.haomeiwen.com/subject/rtvuaxtx.html