文章目录
一、内嵌函数的非本地变量
在一个函数里面在定义的函数,被称为内嵌函数。内嵌函数可以访问闭合范围内(就是外部函数范围)的变量,这些变量被称为非本地变量(nonlocal variable)。
默认情况下,非本地变量是只读的。为了可以修改非本地变量,需要将它们生命为nonlocal
# 代码一
def outer():
def inner():
print('hello')
inner()
outer()
代码一:通过outer()去调用内嵌函数inner
# 代码二
def outer():
a = 1
def inner():
a += 1
inner()
outer()
代码二:此处执行报错,python规则指定所有在赋值语句左面的变量都是局部变量,右边的a值并没有被找到。可以将不可类型更换成可变的列表
# 代码三
def outer():
a = 1
def inner():
nonlocal a
a += 1
print(a)
inner()
outer()
代码三:nonlocal(声明最近一层的外部函数变量)
# 代码四
a = 10
def outer():
a = 1
def inner():
global a
a += 1
print(a)
inner()
outer()
代码四:global (声明的是全局变量)
二、闭包函数
如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。
# 代码五
a = 10
def outer():
a = 1
def inner():
nonlocal a
a += 1
print(a)
inner()
print(inner.__closure__)
outer()
> 2
> (<cell at 0x000001B5F9EBD8E8: int object at 0x00007FFA7480D440>,)
代码五:此处inner调用的是外部函数outer,局部变量,因此输出的是闭包
闭包函数的优势
# 代码六
def outer():
a = 1
def inner():
print(a)
inner()
outer()
代码六:每一次引用inter的变量,都需要调用outer。但是频繁的调用outer里面的变量在内存中就会频繁的生成消失。因此需要储存在内存中。
# 代码七
def outer():
a = 1
def inner():
print(a)
return inner
inn = outer()
inn()
代码七:利用函数名的特点,将全局的变量inn指向闭包函数inner的内存地址。即将值储存在内存中。并且闭包函数inner一直在使用外部函数outer的值a = 1,这样值就不会跟随outer外部函数调用一次就消失,从而延长了外部函数值a = 1 的周期