函数的嵌套
在Python中,函数可以互相嵌套,即在一个函数内部定义另一个函数。包裹在外层的叫做外函数, 内层的就是内函数。
def outer():
def inner():
print("我是inner函数")
outer()
注意:
- 内部函数不能直接在函数外部调用。
- 调用外部函数后,内部函数也不能在函数外部调用。
- 内部函数可以在函数内部调用,但需要先定义再调用。
- 在其他语言中有预加载的机制,提前把函数驻留到内存中,然后再去编译脚本内容,但Python没有预加载函数的机制,只能先定义再调用。
例如,外函数是outer
,中间函数是inner
,最里层是smaller
,调用smaller
函数:
def outer():
def inner():
def smaller():
print("我是smaller函数")
smaller()
inner()
outer()
在Python中,查找变量的调用顺序采用LEGB原则(即就近原则):
- L —— Local(function);当前函数内的作用域 (局部作用域)
- E —— Enclosing function locals;外部嵌套函数的作用域(嵌套作用域)
- G —— Global(module); 函数外部所在的命名空间(全局作用域)
- B —— Builtin(Python);Python内置模块的命名空间(内建作用域)
依据就近原则,从下往上,从里向外,依次寻找。
def outer():
def inner():
def smaller():
print(a)
smaller()
inner()
outer()
nonlocal
在Python中,nonlocal
关键字用于在嵌套函数中修改上一层函数作用域中的变量。
nonlocal
遵循LEGB原则,它会找当前空间上一层的变量进行修改。- 如果上一层空间没有,继续向上寻找。
- 如果最后找不到,直接报错。
注意:nonlocal
只能修改局部变量。
nonlocal
找当前空间上一层的变量进行修改
def outer():
a = 10
def inner():
nonlocal a
a = 20
print(a)
inner()
print(a)
outer()
如果上一层空间没有,nonlocal
继续向上寻找
def outer():
a = 20
def inner():
a = 15
def smaller():
nonlocal a
a = 30
print(a)
smaller()
print(a)
inner()
print(a)
outer()
如果最后找不到,nonlocal
直接报错
a = 20
def outer():
def inner():
def smaller():
nonlocal a
a = 30
print(a)
smaller()
print(a)
inner()
print(a)
outer() # This will raise an error
不通过nonlocal
是否可以修改局部变量
def outer():
lst = [1,2,3]
def inner():
lst[-1] = 3000
inner()
print(lst)
outer() # This will print [1, 2, 3000]
在这个例子中,我们修改了列表lst
的最后一个元素,这是因为列表是可变的数据类型,我们可以直接修改它的元素,而不需要使用nonlocal
关键字。