函数作用域和匿名函数
一、匿名函数
匿名函数:lambda函数
# 不带参数情况
f1 = lambda: 123
res = f1()
print(res) #123
# 等同于函数
def f1():
return 123
res = f1()
print(res) #123
# 带参数情况
f2 = lambda a, b: a + b
res = f2(5, 6)
print(res) #11
等同于函数
def f2(a, b):
return a + b
res = f2(5, 6)
print(res) #11
二、全局变量、局部变量
-
局部变量:函数内部定义的变量,为局部变量,函数外无法调用。------局部作用域
-
全局变量:函数外定义的是全局变量----全局作用域
num = 100
def f():
num = 200
print(num) # 100 函数执行但没有返回值所以是 num = 100
print(num)
f() # 200 调用了函数所以num = 200
print(num) # 100 函数调用完内存直接释放 所以num 指向第一个 num = 100
- 在函数内部定义全局变量: global
num = 100
def f():
global num #直接改变全局变量 num = 200
num = 200
print(num)
print(num) # 100 没调用函数前
f() # 200 调用函数
print(num) # 200 调用函数后应为 global所以全局变量
三、函数的嵌套
嵌套:我们在f1函数内又定义了一个函数,我们调用f1函数,f1函数又会调用f2函数。
def f1():
print("f1外层函数”)
def f2():
print("f2内层函数")
return f2()
f1() # f1内层函数
函数嵌套时,内层函数想要使用外部函数变量,nonlocal
def f1():
num = 88
def f2():
nonlocal num #内层想要使用外层变量必须 +nunlical否则无法执行
num += 1
return num
return f2() #应为要执行2层函数所以直接返 回f2的值
y = f1()
print(y) # 89
四、闭包
函数里面嵌套函数,外层函数返回内层函数的函数名,这种情况就叫做闭包
-
直接调用f1函数,此时执行了print,定义了一个f2函数,同时返回了f2函数名
-
用变量y接收f2函数名
-
变量名+(),实现了函数的调用
# 不带参数
def f1():
print("f1外层函数”)
def f2():
print("f2内层函数")
return f2
y = f1()
y() # f1外层函数 f2内层函数
# 带参数
def f1(numl):
print("f1内层函数", numl)
def f2(num2):
print("f2内层函数", num2)
return f2
a = f1(6666) #a不调用 f2函数一直存在
a(5555) # f1内层函数 6666 f2内层函数 5555
五、递归函数:
#5! 1*2*3*4*5 阶乘
分析
5*4*3*2*1 <-----f(5) = 5*f(4)
4*3*2*1 <-----f(4) = 4*f(3)
3*2*1 <-----f(3) = 3*f(2)
2*1 <-----f(2) = 2*f(1)
1 <-----f(1) = 1 终止
def f(n):
if n == 1:
return 1
return n * f(n-1)
a = f(5)
print(a) # 120
六、总结
总结
1.函数内的变量,外部访问不了
2.函数执行完毕后,函数内的变量会被销毁
3.需求:执行完函数后,我们需要保留函数中某个变量
4.处理:在函数内部去定义一个函数,用内部函数去保存这个变量,我们将内层函数的函数名,当做返回值返回,不调用
5.那这个时候内层函数就把这个需要保留的变量给包含在它的内层空间,这就是闭包