函数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) # 是的

 

posted on 2020-05-13 18:47  fdsimin  阅读(291)  评论(0编辑  收藏  举报