• 函数嵌套 闭包 与 函数作用域


    一、作用域

      函数的命名空间可以作用域可以划分为:LEGB四种,使用缩进来规定。  不同的命名空间的变量可以同名。

        本地  local      本地使用,在函数缩进中,代表着本地缩进

        封闭  enclosing    在嵌套函数中使用,

        全局  global    任何地方都能使用,模块的顶层

        内置  Builtin       内置,比如 int,内置函数等。

    1.1 作用域的范围 与 搜索次序

      

      从里到外所搜: 本地 -》封闭-》全局

    1.2 作用域规则

      搜索规则 本地 -》封闭-》全局   从里到外 一层层修改。

      修改规则:  本地可以引用全局的变量,但是不可以修改上一级的变量。

          (注意复杂的数据结构,list,dict 修改他们的二级数值,并不算修改本身。详见:深浅拷贝章节)

    i = 1
    def test():
        i += 1   # 等同与 i = i + 1 ,这里的i 都是全局变量。 在规则中,不可以修改全局变量。
     
    test()    
    
    UnboundLocalError: local variable 'i' referenced before assignment                 

    对于复杂结构的数据:

    li = [1,2,3,4]
    def test():
        li[0] = 100
        li.append(200) #  对于复杂的数据节后,可以直接修改二级的,并不算修改本身
    test()
    print(li)
    
    结果:
    [100, 2, 3, 4, 200]

    二、内嵌函数

      在一级函数内部,定义函数,可在内部直接运行函数,也可以返回函数,这就是内嵌函数,也叫做封闭作用域。

    def cal(a, b):
        def add(a,b):
            print (a+b)
        def sub(a,b):
            print(a-b) 
        def mul(x,y):
            print (a*b)
    
        add(a,b)
        sub(a,b)
    
        return mul
    cal(1,3)()

    三、闭包函数

      闭包函数是内嵌函数的升级版本,  返回  内嵌函数名 与 自由变量(非全局变量,是一级函数的变量)的绑定体。

      一般函数执行完毕,内部的变量的就消亡了,但是闭包的函数的存在一个封闭空间,不会在一级函数运行完毕而消亡。

    def hellow():
        s = 'i AM'      # 自由变量
        def say():
            print(s)
        return say      # 返回内嵌函数名,但是绑定了自由变量
    x = hellow()
    x()

    闭包函数 也遵循了,不能修改上一级变量的特征。

    def hellow():
        s = 'i AM'
        def say():
            s += ''   #修改上一级变量,报错
            print(s)
        return say
    x = hellow()
    x()
    运行结果:
    UnboundLocalError: local variable 's' referenced before assignment

    四、修改上一级的变量

      上面一直说不能修改和赋值,那一定要修改和赋值呢?  

      python中引进了  gloable 和 nolocal 两个关键字。

    4.1 global

    global的两个作用:

    • 声明一个全局变量

    • 在局部作用域想要对全局作用域的全局变量进行修改时,需要用到 global(限于字符串,数字)

    def func():
        global a            #声明为全局变量
        a = 2
        print(a)
    
    func()
    print(a)
    
    计算结果:
    2
    2

    4.2 nolocal

    • 不能修改全局变量
    • 在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变
    def add_b():
        b = 42
        def do_global():
            b = 10
            print(b)
            def dd_nonlocal():
                nonlocal b  # 只对上一层起作用
                b = b + 20
                print(b)
            dd_nonlocal()
            print(b)
        do_global()
        print(b)
    
    add_b()
    
    
    计算结果:
    10
    30
    30
    42

      

      

     

         

  • 相关阅读:
    Repository Pattern with Entity Framework 4.1 and Code First
    Entity Framework 4.1/4.3 之四(DBContext 之 1 DBContext 是谁)
    C# 依赖注入
    explicit关键字
    enum关键字
    #pragma once
    #if 0 #end if
    assert
    存储类型
    const关键字
  • 原文地址:https://www.cnblogs.com/louhui/p/8953443.html
Copyright © 2020-2023  润新知