• 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)
  • 相关阅读:
    CSP2019题解
    [NOI2019]弹跳(KD-Tree)
    集合框架面试题
    注解
    WiFi攻防
    简单完整讲述Servlet生命周期
    Java多线程
    Java--面向对象讲解
    layUi
    java提高篇(三)-----理解java的三大特性之多态
  • 原文地址:https://www.cnblogs.com/libolun/p/13350561.html
Copyright © 2020-2023  润新知