python--作用域、闭包
作用域
局部变量和全局变量
全局变量:一般定义在函数外面,任何函数都可以访问 ps:访问的含义是只能读取数据
局部变量:一般定义在函数内部,只有本函数才能对其增删改查
LEGB的规则
legb就是python中的一种查找顺序(由上而下)
- locals 是函数内的名字空间,包括局部变量和形参
- enclosing 外部嵌套函数的名字空间(闭包中常见)
- globals 全局变量,函数定义所在模块的名字空间
- builtins 内置模块的名字空间
当python在查找变量使用时,会先从locals中查找,若为找到,则会去enclosing中查找,最后会找到builtins中,若还未找到则会抛出异常,程序结束。
程序最终会找到builtins中,我们可以直接在builtins中添加变量,这样每个模块就都能访问到他了,但是这个方法过于变态,不推荐大家使用。
global与nonlocal
global用于不可变类型想在函数内修改某个全局变量的值得时候,要事先声明这个变量为全局变量,而可变类型则不需要声明
nonlocal 用于内层函数想要访问外层函数的局部变量时,则需要用nonlocal声明这个变量,同样可变类型不需要声明。
number = 10 # 声明一个不可变类型的全局变量
list1 = [1, 2, 3, 4] # 声明一个不可变类型的全局变量
def update(): # 一个函数
global number # 加上声明即可,去除3的错误
c = 10 # 在函数内声明一个不可变的局部变量
print("number = ", number) # number = 10
number += 1 # 3.若不加声明number为全局变量,修改他的值则会报错
# UnboundLocalError: local variable 'number' referenced before assignment
list1.append("5")
print(list1) # [1, 2, 3, 4, '5'] 可变类型数据则不需要声明
# 以上操作在函数外面输出number、list1则会发现,两者都已经改变。
def out_fun(): # 外部函数
a = 0 # 在函数内声明一个不可变的局部变量
def in_fun(): # 内层函数
nonlocal a # 则使用函数里局部变量a
# global a # 则使用全局变量a
print(a)
a += 1
# 此时out_fun函数内有一个局部变量,而外面也有一个a的全局变量,
# 同时如果只是输出a的值则不需要声明a是全局变量的,还是函数内局部变量的a
in_fun()
update()
out_fun()
globals()与locals()
globals()输出全局变量
locals()则输出局部变量
两者是相对来说的,如果两个放在同一个地方,则输出是一样的
number = 10 # 声明一个不可变类型的全局变量
list1 = [1, 2, 3, 4] # 声明一个不可变类型的全局变量
def update(): # 一个函数
global number # 加上声明即可,去除3的错误
c = 10 # 在函数内声明一个不可变的局部变量
print("number = ", number) # number = 10
number += 1 # 3.若不加声明number为全局变量,修改他的值则会报错
# UnboundLocalError: local variable 'number' referenced before assignment
list1.append("5")
print(list1) # [1, 2, 3, 4, '5'] 可变类型数据则不需要声明
# 以上操作在函数外面输出number、list1则会发现,两者都已经改变。
print("------update里的locals------")
print(locals())
# {'c': 10}
def out_fun(): # 外部函数
a = 0 # 在函数内声明一个不可变的局部变量
def in_fun(): # 内层函数
nonlocal a # 则使用函数里局部变量a
# global a # 则使用全局变量a
print(a)
a += 1
# 此时out_fun函数内有一个局部变量,而外面也有一个a的全局变量,
# 同时如果只是输出a的值则不需要声明a是全局变量的,还是函数内局部变量的a
in_fun()
print("------out_fun里的locals------")
print(locals())
# {'in_fun': <function out_fun.<locals>.in_fun at 0x000002C73C0657B8>, 'a': 1}
print("------全局的globals------")
print(globals())
"""输出:
{'__name__': '__main__',
'__doc__': None,
'__package__': None,
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000002C73BDFB048>,
'__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>,
'__file__': 'D:/python-workspace/gp-python-day08/test.py',
'__cached__': None, 'number': 10, 'list1': [1, 2, 3, 4],
'update': <function update at 0x000002C73C0656A8>,
'out_fun': <function out_fun at 0x000002C73C065730>}
"""
update()
out_fun()
闭包
闭包的含义
闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)(外层函数传入一个参数a, 内层函数依旧传入一个参数b, 内层函数使用a和b, 最后返回内层函数)
闭包的条件
- 在一个函数中定义了另一个函数
- 内层函数使用了外层函数的变量
- 返回值是内层函数
def outer_func(n):
a = 10
def inner_func():
r = a + n
print('r的值:', r)
print(locals())
return inner_func
# result = outer_func(1)
# print(result)
# inner_func()
result = outer_func(1) # result = inner_func
print(result) # 内部函数的地址
# 调用内部函数
result()