加载中...

函数补充

函数的嵌套

在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关键字。

posted @ 2024-03-02 15:07  江寒雨  阅读(42)  评论(0)    收藏  举报