• Python 基础之函数的嵌套与nonlocal修改局部变量及闭包函数


    一.函数的嵌套

    嵌套在外层,称之为外函数

    嵌套在里层,称之为内函数
    #:
    def outer():

        def inner():
            print("I'm inner")
        def inn2():
            print("12345")
        inn2()
        inner()
    outer()

    #inner()

    (1)内部函数可以直接在函数外部调用吗 不可以
    (2)调用外部函数后,内部函数可以在函数外部调用吗 不可以
    (3)内部函数可以在函数内部调用吗  可以
    (4)内部函数在函数颞部调用时,是否有先后顺序  不可以

    #外部函数outer 里面是inner  ,inner里面还嵌套一个smaller 内函数,调用smaller
    #:

    #a = 17
    def outer():
        #a = 16
        #id = 99
        def inner():
            #a = 15
            def smaller():
                #a = 10
                print(id)
                print("I'm smaller")
            smaller()
        inner()
    outer()

    #LEGB (就近找变量原则)

    #寻找变量的调用顺序采用LEGB原则(即就近原则)

    L -- Local(function): 当前函数内的作用域  (局部作用域) (局部命名空间

    E -- Enclosing function locals:外部嵌套函数的作用域 (嵌套作用域) (局部命名空间)

    G -- Global(module) :函数外部所在的命名空间    (全局作用域) (全局命名空间)

    B -- Builtin(Python):python内置模块的命名空间 (内建作用域) (内建命名空间)

    依据就近原则, 从上往下 从里向外 依次寻找

    #注意点
    如果先前局部变量存在a,删除之后再获取就获取不到,
    如果先前不存在该局部变量,默认向上按照LEGB原则依次寻找
    #:
    a = 10
    def func():
        a = 20
        del a
        #print(a)
    func()
    print(a)

     

    二.nonlocal 修改局部变量

    nonlocal 专门用于修改局部变量
    (1)它自动寻找上一层空间的局部变量用来修改
    (2)不停的向上寻找
    (3)如果再也找不到了,直接报错
    #(1) nonlocal 符合LEGB原则
    def outer():
        a = 15
        def inner():
            nonlocal a
            a = 17
            print(a)
        inner()
        print(a)
    outer()

    #(2)nonlocal 修改的是局部变量,不是全局变量
    a = 16
    def outer():
        a = 10
        def inner():
            #a = 11
            def smaller():
                nonlocal a
                a +=3
                print(a)
            smaller()
        inner()
    outer()

    #(3) 不是用nonlocal 是否可以修改局部变量?可以
    def outer():
        # a = 3
        lst = [1,2,3,4,5]
        def smaller():
            lst[2] +=5
        smaller()
        print(lst)
    outer()

     

     

    三.闭包函数

    闭包:
        内函数使用了外函数的局部变量
        并且外函数把内函数返回出来的过程是闭包
        这个内函数叫做闭包函数
    #(1)  基本语法
    def outer():
        a = 5
        b = 6
        #inner 是闭包函数
        def inner():
            print(a,b)
        return inner
    res = outer()
    print(res)
    res()

    #获取闭包函数使用的变量: __closure__ ,cell_contents (了解)
    tup = res.__closure__
    print("=====1======")
    print(tup)
    #获取元组里面第一个元素
    obj = tup[0]
    print(obj)
    #使用cell_contents来获取单元对象当中的值
    res = obj.cell_contents
    print(res)

    obj2 = tup[1]
    res2 = obj2.cell_contents
    print(res2)
    print("<======2=======>")

    #闭包的特点:
        内函数使用了外函数的局部变量,外函数的局部变量与内函数发生绑定,延长该变量的生命周期
        (实际内存给它存储了这个值,暂时不释放)
    #(2)闭包函数特点
    #:

    def famil():
        dejie = "one"
        erjie = "two"
        #money 局部变量因为在闭包函数中使用,于是发生绑定,延长该变量的生命周期
        money = 100000

        def dajie_hobby():
            nonlocal money
            money -=30000
            print("大姐喜欢花钱,喜欢买兰博基尼,喜欢买channel,家里钱还剩下%d" % (money))

        def erjie_hobby():
            nonlocal money
            money +=15000
            print("二姐喜欢赚钱,,家里钱赚了现在变成%d钱" % (money))

        def master():
            #返回一个元组,元组里面的每一个元素是函数
            return (dajie_hobby,erjie_hobby)
        return master
    func = famil()
    tup = func()
    print(tup)
    #大姐函数
    dajie = tup[0]
    dajie()
    #二姐函数
    erjie = tup[1]
    erjie()

     

    输出结果为:

    大姐喜欢花钱,喜欢买兰博基尼,喜欢买channel,家里钱还剩下70000

    二姐喜欢赚钱,,家里钱赚了现在变成85000

     

  • 相关阅读:
    TeXLive安装过程
    js 如何获取class的元素 以及创建方法getElementsByClassName
    点击返回
    MVC框架实现文件的上传(支持多文件上传)
    团购倒计时抢购功能
    获取取当前页 地址分割字符串
    网页内容截取部分打印
    HttpFileCollection 实现多文件上传
    JS如何获取URL
    正则表达式 占位符 替换
  • 原文地址:https://www.cnblogs.com/hszstudypy/p/10851333.html
Copyright © 2020-2023  润新知