zoukankan      html  css  js  c++  java
  • 函数globals和locals用法, LEGB原则, 闭包函数 , 匿名函数

    1,  locals()和globals()

    local是获取当前作用域的所有内容

    在函数体内使用locals()是局部空间作用域,获取到调用之前的所有变量,返回字典
    在函数体外使用locals()是全局空间作用域,获取到打印之前的所有变量,返回字典

    a = 1
    def func1():
        b=1
        res = locals()
        print(res)
    func1()  # {'b': 1}
    res2 = locals()
    print(res2)  # 返回了系统字典

    globals是获取全局作用域的所有内容

    在函数体内,使用globals(),获取的是全局空间作用域,调用之前的所有变量,返回字典
    在函数体外,使用globals(),获取的是全局空间作用域,打印之前的所有变量,返回字典

    a= 1
    def func1():
        b=2
        res1 = globals()
        print(res1)
    func1()  # ...'a': 1...
    c= 3
    res2 = globals()
    print(res2)  # ...'a': 1,'c': 3...

    通过系统的字典来动态添加变量

    dict1 = globals()
    str = "字符串变变量名"
    dict1[str]="变成功了"
    print(字符串变变量名)  # 变成功了

    2,  变量的LEGB原则:

                                       L:Local(function),函数体内的作用域,局部作用域
                                       E:Enclosing function locals,外部嵌套函数的作用域,嵌套作用域
                                       G:Global(module),函数外部所在的命名空间,全局作用域
                                       B:Builtin(Python),python内置模块的命名空间,内建作用域
                                       变量遵循LEGB原则,就近查找变量值

    3,  nonlocal(): 专门用来修改当前作用域的上一级的局部变量,如果上一级都找不到就报错,一定注意这个是针对于局部变量的修改,不包括全局变量

    a = 10
    def func1():
        a = 20
        def func2():
            def func3():
                nonlocal a
                a = 30
                print(a) # 30
            func3()
            print(a) # 30
        func2()
        print(a) # 30
    func1()
    print(a) # 10

      也可以用列表来修改函数内部的变量值:

    def func1():
        list1=[10]
        def func2():
            list1[0] = 50
            print(list1) # [50]
        func2()
    func1()

    4, 闭包函数:内函数使用了外函数的变量,外函数将内函数返回出来的过程,叫做闭包,里面的内函数叫做闭包函数

    def outter(name):
        def inner():
            print("外面给我传了"+name)
        return inner
    res = outter("张三")  # 此步骤是将inner函数return的值赋值给res
    res() # 外面给我传了张三  因为res()相当于调用了inner函数,所以触发了inner的执行

       闭包小案例:

    def jiaqi(time):
        print("假期开始了,一共有{}天".format(time))
        def dayouxi():
            nonlocal time
            time -= 3
            print("我打游戏用了3天,还剩{}天".format(time))
        def kandianshi():
            nonlocal time
            time -= 4
            print("我看电视用了4天,假期还剩{}天".format(time))
        def fadai():
            return [dayouxi,kandianshi]
        return fadai
    func = jiaqi(8) # 假期开始了,一共有8天
    list1 = func()
    list1[0]() # 我打游戏用了3天,还剩5天
    list1[1]() # 我看电视用了4天,假期还剩1天

         获取闭包函数使用的变量 __closure__ ,和cell_contents

    res = jiaqi(8).__closure__
    print(res)
    # (<cell at 0x0000021AD1D08588: function object at 0x0000021AD1D94598>, <cell at 0x0000021AD1D085B8: function object at 0x0000021AD1D94620>)
    
    res2 = res[0].cell_contents
    print(res2)
    # <function jiaqi.<locals>.dayouxi at 0x0000021AD1D94598>
    res3 = res[1].cell_contents
    print(res3)
    # <function jiaqi.<locals>.kandianshi at 0x0000021AD1D94620>

        闭包函数的特点:  内函数使用了外函数的局部变量,该局部变量与内函数发生绑定,延长了该变量的生命周期

    def func1(str1):
        def func2(str2):
            print(str1+"可以变成"+str2)
        return func2
    res = func1("")
    res("美丽的蝴蝶")

        闭包函数的意义:  闭包函数可以优先使用函数的局部变量,外部无法直接使用函数内的局部变量也无法更改函数的局部变量,从而对函数内的局部变量形成了保护作用

    def func1():
        num = 0
        def func2():
            nonlocal num
            print(num)
            num += 1
    
        return func2
    res = func1()
    res() # 0
    res() # 1
    res() # 2
    num = 50
    print(num) # 50
    res() # 3
    res() # 4

    5,  匿名函数:  lambda 用一句话来表达只有返回值的函数,具有简洁,高效,方便的特点, 有以下三种表达形式

    # (1) 无参的lambda函数形式:
    func = lambda :"我是一个匿名函数"
    res = func()
    print(res) # 我是一个匿名函数
    
    # (2) 有参的lambda函数形式
    func= lambda a,b:a+b
    res1 = func(2,3)
    print(res1) # 5
    
    # (3) 带有判断条件的lambda表达式
    func = lambda x,y : x if x > y else y
    res2 = func(5,6)
    print(res2) # 6
    # if 条件成立的话返回左边的值,不成立的话返回右边的值

    6,  三元表达式:  如果if条件成立的h话,返回左边的值,不成立的话返回右边的值

    str1 = "我是字符串吗?"
    res = "是的" if type(str1) == str else "不是的"
    print(res) # 是的
  • 相关阅读:
    页面可视化搭建 整理
    单页面应用(SPA)重新部署后,正在浏览的页面如何更新缓存?
    vim 使用
    浏览器缓存 知识点
    http 2.0 新特性
    GoJS 在 vue 项目中的使用
    详解Vue中watch的高级用法
    什么是 PWA?
    代码风格统一工具:EditorConfig 和 静态代码检查工具:ESLint
    vue-cli 3.x 使用
  • 原文地址:https://www.cnblogs.com/fdsimin/p/12884212.html
Copyright © 2011-2022 走看看