locals() 和 globals()
locals ()
获取当前作用域的所有变量
- locals 如果在函数的外面,获取locals()返回值打印之前, 所有的内容.
a = 10
b = 20
res = locals()
c=20
print(res)
d=30
- locals 如果在函数的里面,获取locals调用之前,所有的内容
def func():
f1 = 11
f2 = 12
res = locals()
f3 = 13
print(res)
func()
globals ()
只获取全局变量(无论在函数内外都只获取全局变量)
- globals 如果在函数的外面,获取globals()返回值打印之前, 所有的内容
a = 5
b =15
res = globals()
c = 26
print(res)
d = 27
- globals 如果在函数的里面,获取globals调用之前,所有的内容
z1 = 5
z2 = 6
def func():
f1 = 1
f2 = 2
f3 = 3
res = globals()
f4 = 6
print(res)
z4 = 8
func() #res = globals()
z3 = 7
- globals 动态创建全局变量
globals 返回的是系统的 全局命名空间的字典 ,在空间里面放的全局变量
dic = globals()
print(dic,type(dic))
dic['wangwen'] = 188
print(wangwen)
- globals 可以批量创建全局变量
def func():
res = globals()
# res['a1'] = 1
# res['a2'] = 2
for i in range(5):
# print(i)
res["a%d" % (i) ] = i
'''
"a%d" % (i) # 字符串的格式化
res['a0'] = 0
res['a1'] = 1
res['a2'] = 2
res['a3'] = 3
res['a4'] = 4
'''
func()
print(a0)
print(a1)
print(a2)
print(a3)
print(a4)
locals 更多的用于获取一些变量 , globals更多的用于修改一些变量
函数的嵌套
嵌套在外层,称之外函数
嵌套在里层,称之内函数
def outer():
def inner():
print("我是inner函数")
inner()
outer()
(1)内部函数可以直接在函数外部调用么 不可以
(2)调用外部函数后,内部函数可以在函数外部调用吗 不可以
(3)内部函数可以在函数内部调用吗 可以
(4)内部函数在函数内部调用时,是否有先后顺序 有顺序
无论在函数内还是函数外:都要遵循先定义再调用的顺序
def outer():
# a = 16
# id = 99
def inner():
# a = 15
def smaller():
# a = 10
print(id)
print("我是smaller函数")
smaller()
inner()
outer()
LEGB (就近找变量原则)
找寻变量的调用顺序采用LEGB原则(即就近原则)
B —— Builtin(Python):Python内置模块的命名空间 (内建作用域) (内建命名空间)
G —— Global(module):函数外部所在的命名空间 (全局作用域) (全局命名空间)
E —— Enclosing function locals:外部嵌套函数的作用域 (嵌套作用域) (局部命名空间)
L —— Local(function):当前函数内的作用域 (局部作用域) (局部命名空间)
依据就近原则,从下往上 从里向外 依次寻找
额外注意点:
如果先前局部变量存在a,删除之后再获取就获取不到,
如果先前不存在该局部变量,默认向上按照LEGB原则依次寻找
a = 10
def func():
a = 20
del a
# print(a)
func()
# print(a)
闭包函数
闭包:
内函数使用了外函数的局部变量,
并且外函数把内函数返回出来的过程是闭包
这个内函数叫做闭包函数;
基本语法
def outer():
a = 5
b = 6
# inner 是闭包函数
def inner():
print(a,b)
return inner
res = outer() # res = inner
res() # res() = inner()
- 获取闭包函数使用的变量
__closure__ , cell_contents (了解)
tup = res.__closure__
print(tup)
# 获取元组里面第一个元素
obj = tup[0]
print(obj)
# 使用cell_contents来获取单元对象当中的值
res = obj.cell_contents
print(res)
obj2 = tup[1]
res2 = obj2.cell_contents
print(res2)
闭包函数特点
内函数使用了外函数的局部变量,外函数的局部变量与内函数发生绑定,延长该变量的生命周期
(实际内存给它存储了这个值,暂时不释放)
def majunqiang_family():
dajie = "马蓉"
erjie = "马冬梅"
kuang = "金矿"
# money 局部变量因为在闭包函数中使用,于是发生绑定,延长该变量的生命周期
money = 1000
def dajie_hobby():
nonlocal money
money -= 900
print("大姐喜欢花钱,喜欢买兰博基尼,喜欢买比基尼,喜欢买channel,家里钱还剩下%d" % (money))
def erjie_hobby():
nonlocal money
money += 500
print("二姐马冬梅喜欢赚钱,喜欢上长春扎疫苗,因为假疫苗能赔偿,喜欢卖血,5块钱一瓶,家里钱赚了%d" % (money))
def master():
# 返回一个元组,元组里面的每一个元素是函数
return (dajie_hobby,erjie_hobby)
return master
func = majunqiang_family()
tup = func()
print(tup)
# 大姐函数
dajie = tup[0]
dajie()
# 二姐函数
erjie = tup[1]
erjie()
闭包的特点意义
- 闭包的特点
内函数使用了外函数的局部变量,外函数的局部变量与内函数发生绑定,延长该变量的生命周期
(实际内存给它存储了这个值,暂时不释放)
def outer(num):
def inner(val):
return num + val
return inner
func = outer(10) # func = inner
res = func(21) # func(21) = inner(21)
print(res) # res = num + val = 10 + 21 = 31
'''
代码解析:
num 接收到普通实参10 此刻 num = 10
func = outer(10) # func = inner
res = func(21) # func(21) = inner(21)
print(res) # res = num + val = 10 + 21 = 31
'''
- 闭包的意义
模拟鼠标点击的操作
- 如果使用全局变量num来进行统计,因为作用域太大,容易造成漏洞.不安全
# 如果使用全局变量num来进行统计,因为作用域太大,容易造成漏洞.不安全
num = 0
def click_num():
global num
num+=1
print(num)
# 调用一次函数,累加一次num
click_num()
click_num()
click_num()
num = 100
click_num()
click_num()
- 闭包的意义:闭包可以优先使用外函数中的变量,并对闭包中的值起到了封装保护的作用.外部无法访问.
def click_num():
num = 0
def func():
nonlocal num
num+=1
print(num)
return func
click_num = click_num()
click_num()
click_num()
click_num()
num = 100
click_num()
click_num()