01内部函数
特点:
- 可以访问外部函数的变量
- 内部函数可以修改外部函数的可变类型的变量,比如list1
- 修改外部函数的变量需要声明 ***nonlocal***变量名
- locals() 查看本地变量有哪些,以字典的形式输出
- globals() 查看全局变量有哪些,以字典的形式输出(注意里面会有一些系统的键值对)
# 内部函数
def func():
# 声明变量
n = 100
list1 = [5,9,7,2]
# 声明内部函数
def inner_func():
nonlocal n
n += 100 # 对外部函数的变量修改
# 对list1进行加法操作
for index,i in enumerate(list1):
list1[index] = i + n
list1.sort()
# 调用内部函数
inner_func()
# 使用locals()内置函数进行查看,可以看到在当前函数中声明的内容有哪些
# locals()是一个字典
print(locals())
print(list1)
# 调用函数
func()
----------------------------------------------------
{'inner_func': <function func.<locals>.inner_func at 0x000001F551927400>, 'n': 200, 'list1': [202, 205, 207, 209]}
[202, 205, 207, 209]
02闭包
条件
- 外部函数中定义了内部函数
- 外部函数是有返回值
- 返回值是:内部函数名,不能加()
- 内部函数引用了外部函数的变量
def func():
a = 100
def inner_func():
b = 90
print(a,b)
# 把函数往外扔
return inner_func # 不能加括号,加括号是调用
x = func()
x()
-----------------------------------------------------
100 90
示例:
def func(a,b):
c = 10
def inner_func():
s = a+b+c
print('相加后的结果是:',s)
# 把函数往外扔
return inner_func # 不能加括号,加括号是调用
ifunc = func(6,9) #ifunc = inner_func
# 调用返出来的内部函数
ifunc()
-----------------------------------------------------
相加后的结果是: 25
作用:
保存返回闭包时的状态,不会受到a,b改变的影响
03计数器
def generate_count():
container = [0]
def add_one():
container[0] = container[0]+1
print('当前是第{}次访问'.format(container[0]))
return add_one
counter = generate_count()
counter()
counter()
counter()
----------------------------------------------------
当前是第1次访问
当前是第2次访问
当前是第3次访问
总结
闭包的缺点:
- 作用域没有那么直观
- 因为变量不会被垃圾回收所以有一定的内存占用问题
闭包的作用: - 可以使用同级的作用域
- 读取其他元素的内部变量
- 延长作用域
- 闭包是理解装饰器的基础