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