函数嵌套、名称空间及作用域
1、函数的嵌套
函数内嵌套函数,让内层函数封闭起来,不让外部直接调用
def index():
print("hello world")
def fun():
index()
fun()
将复杂并且小的功能在函数内部调用,解决代码结构不清晰问题
def index():
register()
login()
...
index()
2、名称空间
什么是名称空间?
存放名字与对象绑定关系的地方,如果想访问一个变量值,需要先访问对应的名称空间,拿到名字与对应的内存地址绑定关系
名称空间的分类
1、内置名称空间
python提前定义好的名字,就是存放在内置名称空间
生命周期:python解释器启动的时候生效,关闭python解释器失效
<built-in function print>###内建功能print
2、全局名称空间
python文件级别的名字,伴随着.py文件执行打开,执行结束关闭,if 、while、for内部定义的名字只要执行就会存放在全局名称空间
生命周期:启动执行py文件生效,执行完整个py文件才失效
x = 1 # 存在全局名称空间
if x == 1:
x = 2 # 存在全局名称空间
print(x)
while x == 1:
x = 3 # 此步未执行,如果条件成立执行到则存放在全局名称空间内
print(x)
3、局部名称空间
函数内部定义的名字都是存放在局部名称空间内
生命周期:当调用函数时生效,函数体代码执行完立即失效
x = 3 # 存在全局名称空间
def index():
x = 1 # 存在局部名称空间
print(x) # 同函数体内x可以更改
index()
print(x) # 打印是全局名称空间中x,因为函数执行结束,局部名称空间内x关闭
名称空间查找顺序:
如果从局部名称空间执行查找:局部 > 全局 > 内置,内置找不到就报错
如果从全局名称空间执行查找: 全局 > 内置,内置找不到就报错
名称空间加载顺序:
内置 > 全局 > 局部
x=1 # 第四步查找
def index():
# x = 2 # 第三步查找
def fun1():
# x=3 # 第二步查找
def fun2():
# x=4 # 第一步查找
print(x)
fun2()
fun1()
index()
函数内使用的名字在定义阶段已经规定死了,与你的调用位置无关,在另一个局部空间无法修改
x=1
def index():
x = 2
print(x) # 查找同级局部,如果没有再查找全局,不会被另一个局部名称空间修改
def fun():
x = 3
index()
fun()
>>> 2
x = 1
def inner():
x = 2
def wrapper():
print(x)
wrapper()
inner()
>>>
2
x = 1
def index(arg=x): # 定义阶段默认参数已经传入参数1
print(x)
print(arg)
x = 2
index()
>>>
# 2
# 1
作用域
名称空间的作用范围
1、全局作用域
位于全局名称空间+内置名称空间中的名字属于全局范围,该范围内的名字全局可以调用
2、局部作用域
位于局部名称空间中的名字属于局部范围,该范围内的名字只能在函数内使用,函数调用结束失效
global:声明全局变量,在局部作用域内修改全局名称空间内的变量
x = 1
def index():
# global x # 声明全局变量,将x=1修改为x=2
x = 2
def fun():
print(x) # 先从局部作用域内查找,如果没有则查找全局作用域
index()
print(x)
nonlocal:在局部名称空间声明局部变量,修改外层能找到的局部名称空间内的变量,会从当前函数的外层一层一层查找变量x,若一直到最外层函数,都找不到,则抛出异常
x= 1
def index():
x=2
def fun1():
global x
x=3
def fun2():
x=4
def fun3():
nonlocal x
x = 5
print(f"1,{x}")
fun3()
print(f"2,{x}")
fun2()
print(f"3,{x}")
fun1()
print(f"4,{x}")
index()
print(x)
>>>
# 1,4
# 2,5
# 3,3
# 4,2
# 3
如果没有global或nonlocal,正常在局部修改外部的值不能修改,只有可变类型可以在局部名称空间修改外部的值
l1 =[1,2,3]
def index(a):
l1.append(a)
print(l1)
index(5)
print(l1)
index(6)
>>>
# [1, 2, 3, 5]
# [1, 2, 3, 5]
# [1, 2, 3, 5, 6]
x=1
def index():
x = 2 # 只能修改一层,此层不能被修改
def fun1():
x=3 # 被修改
def fun2():
nonlocal x
x=4
fun2()
print(x)
fun1()
print(x)
index()
>>>
4
2