day12:闭包函数&匿名函数(lambda)
闭包函数
闭包函数的定义:
如果内函数使用了外函数的局部变量
并且外函数把内函数返回出来的过程 叫做闭包
里面的内函数是闭包函数
一个简单的闭包函数示例:
def songyunjie_family(): father = "王健林" def f_hobby(): print("这是我爸爸{}".format(father)) # 内函数使用了外函数的局部变量father return f_hobby # 外函数把内函数返回出来了
复杂的闭包函数(多层)
def mashengping_family(): father = "马云" jiejie = "马蓉" meimei = "马诺" money =1000 def jiejie(): nonlocal money money-=700 print("还剩下{}元".format(money)) def meimei(): nonlocal money money-=200 print("还剩下{}元".format(money)) def big_master(): return (jiejie,meimei) return big_master func = mashengping_family() print(func) # <function mashengping_family.<locals>.big_master at 0x000001F4CB0F5620> # 返回的是元组 tup = func() print(tup) # (<function mashengping_family.<locals>.jiejie at 0x0000013D5B175158>, <function mashengping_family.<locals>.meimei at 0x0000013D5B175268>) # 获取姐姐 jiejie = tup[0] # 获取妹妹 meimei = tup[1] # big_master 是闭包函数,是直接被mashengping_family返回出来的 # jiejie,meimei 是通过big_master间接被返回到函数外面的 # 调用妹妹 meimei() # 还剩下800元 # 调用姐姐 jiejie() # 还剩下100元 # 获取闭包函数所使用的变量 __closure__ res = func.__closure__ print(res) # (<cell at 0x000001AF2B5A76A8: function object at 0x000001AF2B645158>, <cell at 0x000001AF2B5A76D8: function object at 0x000001AF2B645268>) # cell_contents 用来获取单元格对象当中的闭包函数 jiejie = res[0].cell_contents # <function mashengping_family.<locals>.jiejie at 0x0000019161005158> meimei = res[1].cell_contents # <function mashengping_family.<locals>.meimei at 0x0000019161005268> i = jiejie.__closure__[0] # <cell at 0x0000020E9B977708: int object at 0x0000000054928CD0> j = meimei.__closure__[0] # <cell at 0x0000020E9B977708: int object at 0x0000000054928CD0> a = jiejie.__closure__[0].cell_contents # 100 b = meimei.__closure__[0].cell_contents # 100
闭包的特征
内函数使用了外函数的局部变量
那么该变量与闭包函数发生绑定
延长该变量的生命周期
def outer(val): def inner(num): return val+num return inner func = outer(10) # func = inner res = func(15) # res = func(15) =inner(15) print(res) # 25 """ 10实参-->val形参 因为内函数inner是闭包函数 使用了外函数val 那么该变量val生命周期被延长 没有随着函数调用的结束而释放 res = inner(15) => return val+num =>10+15 =>25 """
闭包的意义
闭包的意义:闭包可以优先使用外函数中的变量,并对闭包中的值起到了封装保护的作用,外部无法访问
# 模拟鼠标点击次数 num = 0 def click_num(): global num num += 1 print(num) click_num() # 1 click_num() # 2 click_num() # 3 num = 100 click_num() # 101 click_num() # 102 ''' 很显然,这样是不行的,定义了全局变量100后,值就从100开始加了. 想一个办法,让其就算在中间插入num=100也没用 ''' # 解决方案 def click_num(): num=0 def func(): nonlocal num num+=1 print(num) return func func = click_num() func() # 1 func() # 2 num = 1000 func() # 3 func() # 4 func() # 5
匿名函数
匿名函数 : 用一句话来表达只有返回值的函数
语法:lambda 参数 : 返回值
目的:追求代码:简洁,高效
1.无参的lambda 表达式
# 1.无参的lambda 表达式 def func(): return "123" # 改写 func = lambda : "123" res = func() print(res)
2.有参的lambda 表达式
# 2.有参的lambda 表达式 def func(n): return type(n) # 改写 func = lambda n : type(n) print( func([1,2,3]) )
3.带有判断条件的lambda 表达式
def func(n): if n % 2 == 0: return "偶数" else: return "奇数" func = lambda n : "偶数" if n % 2 == 0 else "奇数" res = func(17) print(res)
4.三元运算符(三目运算符)
""" 语法: 真值 if 条件表达式 else 假值 如果条件表达式为真,返回真值,否则返回假值 """ n = 16 res = "偶数" if n % 2 == 0 else "奇数" print(res)
5.小练习
# 小练习 , 传递两个数, 返回较大的那一个 def func(x,y): if x>y: return x else: return y func = lambda x,y : x if x>y else y res = func(200,100) print(res)