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)

 

posted @ 2020-07-20 23:05  iR-Poke  阅读(255)  评论(0编辑  收藏  举报