开发者学堂课程【Python 入门 2020年版:闭包的概念】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/639/detail/10346
闭包的概念
内容介绍:
一、 函数的嵌套
二、 闭包的概念
三、 闭包的应用
一、 函数的嵌套
1、嵌套函数是有一些高级的,接下来讲函数如何嵌套,写一个 def outer 函数,再写一个def inner函数,然后在这里面写 print(’我是outer函数’),print(’我是 inner 函数’)
,最后写 return ‘hello’
def outer():
print('我是outer函数’)
def inner():
print('我inner函数')
return hello
这个 inner 函数是定义在 outer 函数内部的一个函数,因为是在内部定义的,所以在外面是用不了的,打一个最简单的比方,m 等于 100,它叫局部变量,这个局部变量定义在函数内部只能在函数内部使用,在外面用不了。
同样的道理,在函数内部定义的一个函数,在外面也是用不了的,它也会报错。 如果要用的话,一般情况下在外面不能调,可以在内部调。比方说现在需要一个参数 x,
If x>18
inner()
自己内部调一下 inner,写 outer(12)运行一下这个,它只会调‘我是 outer 函数’,inner 函数没有调,但是如果写 outer(21),运行一下发现它两个都调了2、所以可以通过参数的形式,把这个参数传进来,然后它再用到这个参数,再调用自己内部的函数,这样是可以的,没有问题的。
这是一种内部函数嵌套函数,函数的嵌套函数是有一点点高级的,而且用起来的话也不是那么的简单,有一点点难。
二、 闭包的概念
1、这里面涉及一个东西叫闭包,闭包这个概念仅作为了解,这个不太好说明,很多语言里都有类似的闭包概念,但是每一个闭包在它的语言里的大概使用场景也不太一样。
2、闭包在 python 里的应用。
def outer():
def inner():
pass
return inner
首先需要函数的嵌套,然后还需要一个外部函数返回内部函数,而不是内部函数的调用,不能写括号。
在一个函数里对外部函数的作用域,还需要再来一个内部的私有变量,比方说x=10 ,这样又是一个变量,这个是在外部函数里定义了一个变量 x,它其实不是一个全局变量,而是一个局部变量。
然后有一个局部变量,在外部函数里返回内部函数,然后在内部函数里写 y=x+1 ,在外部函数里有一个内部函数,内部函数会操作这个局部变量,最后返回的时候,这个外部返回函数返回 inner 函数,这个就是闭包的一个概念,这其实很抽象,仅作为了解。
def outer():
x=10
def inner():
y=x+1
return inner
3、闭包等于函数块加引用环境,引用环境就是用到的内部的参数。闭包讲起来不是特别简单,只知道一下如果在一个函数里,对外部作用域,但不是全局作用域,在内部函数里操作了一个外部作用域,外面的一个数据,但是这个数据又不是全局变量,那么内部函数就被认为是一个闭包。有点绕了解一下就行。
三、闭包的应用
1、本节的重点不在于闭包,而是用闭包做一个功能。有一个内容需要了解,如果现在要把 x=10 改一下,在内部直接直接写个 x=20 就会出问题,这个写法是有问题的,因为一旦这么写的话,y=x+1 这行代码就有问题了。
自己声明了一个 x=20,先说明一下这个不是修改外部的 x 变量,而是在 inner 函数内部又创建了一个新的变量 x,本来有 x 了,但是你自己又定了一个 x,它会报错。
2、内部函数如何修改外部函数的局部变量。X=10 它是一个局部变量,就是在外部函数里面定义的一个局部变量,如果要改变,需要写
nonlacal x
def outer():
x = 10
def inner():
nonlocal x
y=x+1
x= 20
x=20 和 y=x+1 不能换位置, x 是新定义的 x,而不是外部的这个 x,是在内部函数里又定义了一个新的。
如果想要改外部函数的x变量的值的话,要加一个叫nonlocal x,此时这里的x不再是新增的变量而是外部的局部变量x。
global 是全局的,不能用 global,而要用 nonlocal ,x 不是全局而是变量,要改函数里面的变量要用 nonlocal ,这个了解一下就行,用到的频率不多。
这种高级的用法在 python 底层里有,但是不需要看。
3 接下来要讲的东西会一定程度上用到上述讲到的内容,但是不讲源码,只是讲语法,告诉怎么样用。
思考 y 运行的结果是等于 11 还是 21,y 如果运行的话,现在这个值应该是 11,写个 outer()这是调 outer,那怎么调 inner 呢?
print 一下 inner 里的 y 等于多少,这个 outer 调完之后拿到 inner 里,再在outer()后面加一个括号变成 outer()()
def outer():
x = 10
def inner():
nonlocal x
y=x+1
print(‘inner里的y=’,y)
x= 20
return inner
outer()()
运行结果为 inner 里的 y=11 ,而不再是 20,了解一下,这个是只是说一下它这个格式啊,这个格式是闭包的一个格式,知道一下就行。
一会用这个去实现一个功能,这个功能的话需要注意,它有一点点高级,这个语法内部的实现是 python 底层做的,我们需要做的就是用了这个语法之后,我们到底做了什么事儿,这个是我们需要知道的。