一、闭包
1、函数嵌套
f1函数内又定义了一个f2函数,我们调用f1函数,f1函数内部又调用了f2函数,这就叫函数的嵌套
def f1():
print("f1外层函数")
def f2():
print("f2内层函数")
return f2()
f1()
'''
f1外层函数
f2内层函数
'''
函数名即变量(一个名字对应一个内存地址)
函数名: 即变量名
函数名(): 即函数执行
2、闭包
函数嵌套时。外层函数返回内层函数的函数名,这种情况叫闭包
def f1():
print("f1外层函数")
def f2():
return 5
return f2
a = f1() # a==>f2
print("a的执行结果:", a())
'''
运行结果:
f1外层函数
a的执行结果: 5
'''
3、带参数的情况
def f1(num1):
print(num1)
def f2(num2):
res = num1 + num2
print(res)
return f2
a = f1(6) # 6
a(8) # 14
4、总结
- 函数内的变量,函数外部访问不了
- 闭包是概念,不是某种函数类型,这是一种特殊的函数调用
- 闭包可以得到外层函数的局部变量,是函数内部和外部沟通的桥梁
二、装饰器
装饰器其实就是一个闭包,把一个函数当做参数然后返回一个替代版函数
1、不带参数的单层装饰器
def outer(func):
def inner():
print("在原有功能前增加新功能")
r = func()
print("在原有功能后增加新功能")
return r
return inner()
# @outer表示
# 1、执行outer函数,并将下方的函数名作为参数赋值给outer函数
# 2、将outer函数的返回值重新赋值给下方的函数
@outer
def f1():
print("原功能模块")
def f2():
print("f2")
#.......
def fn():
print("fn")
运行结果:
2、多层装饰同一个函数
def outer_1(func):
def inner(*args, **kwargs):
print("在原有功能前增加新功能1")
r = func(*args, **kwargs)
print("在原有功能后增加新功能1")
return r
return inner
def outer(func):
def inner(*args, **kwargs):
print("在原有功能前增加新功能")
r = func(*args, **kwargs)
print("在原有功能后增加新功能")
return r
return inner
@outer_1
@outer
def fn(a, b, c):
print(a + b + c)
fn(1, 2, 3)
运行结果:
3、练习
定义一个函数,能够输入字典和元组,函数返回一个字典和元组,字典的value值和元组的值交换。
- 面向过程编程
tu = {"vae", 32, 180}
di = {"name":"hh", "age":18, "height":190}
print(tuple(di.values())) # ('hh', 18, 190)
# 配对
print(dict(zip(di.keys(), tu))) # {'name': 'vae', 'age': 32, 'height': 180}
- 函数式编程:便于我们随时调用,减少代码的重复性
def func(a, b):
print(tuple(b.values())) # ('hh', 18, 190)
# 配对
print(dict(zip(b.keys(), a))) # {'name': 'vae', 'age': 32, 'height': 180}
func(tu, di)