• 函数对象函数嵌套名称空间与作用域闭包函数


    函数对象

    # def func():
    #     print('from func')
    
    
    #1、可以赋值
    # f = func
    # print(f)
    # f()
    #2、可以当作参数传给另外一个函数
    # def foo(x):
    #     # print(x)
    #     x()
    # foo(func)
    
    #3、可以当作函数的返回值
    # def foo(x):
    #     return x          # 返回func函数的内存地址
    # res=foo(func)      # 当作foo函数的参数  传入函数的内存地址
    # print(res)
    #4、可以当作容器类型的元素
    # l=[func,]     #可以当作列表里面的元素,本质是内存地址存放在列表中
    # print(l)
    # l[0]()        # 从列表找到函数内存地址   括号引用
    

    函数嵌套

    函数嵌套的调用

    # 函数的嵌套调用
    
    # def max2(x,y):
    #     if x >y :
    #         return x
    #     else:
    #         return y
    #这是比较两个参数的函数  功能是比较出来大的有返回值
    # def max4(a,b,c,d):
    #     res1=max2(a,b)
    #     res2=max2(res1,c)
    #     res3=max2(res2,d)
    #     return res3
    # print(max4(1919,2222,3423,789))
    # 这个是把上面的比较两个参数大小的函数  嵌套到另一个函数里面 比较多个参数的大小
    

    函数嵌套的定义

    # 函数的嵌套定义
    #例子1
    # def f1():
    #     x=10
    #     def f2():
    #         print('from f2')
    # f1()
    # print(x)      变量定义在内部 外部访问不到
    # print(f2)      变量定义在内部 外部访问不到
    
    # 例子2
    # def f1():
    #     x=10
    #     def f2():
    #         print('from f2')
    #     print(x)
    #     print(f2)
    #
    # f1()
    

    名称空间与作用域

    名称空间与作用域的关系是在函数定义阶段(扫描语法时)就确立的,与什么时候调用以及调用位置无关

    名称空间

    名称空间namespaces:存放名字与内存地址关系的地方

    大致分为:

    内置名称空间:存放内置的名字
            生命周期:python解释器启动则产生,关闭则删除
    全局名称空间:存放的是顶级的名字
            生命周期:运行python文件则产生,运行完毕则销毁
    局部名称空间:存放的是函数内的名字
            生命周期:调用函数则产生,函数调用完毕则销毁
    

    核心:

    名称空间的加载顺序是:内置名称空间->全局名称空间->局部名称空间,而查找一个名字,必须从三个名称空间之一找到,查找顺序为:局部名称空间->全局名称空间->内置名称空间。

    1、内置名称空间

    伴随python解释器的启动/关闭而产生/回收,因而是第一个被加载的名称空间,用来存放一些内置的名字,比如内建函数名

    print(len)
    >>><built-in function len>  # built-in 内置
    

    2、全局名称空间

    伴随python文件的开始执行/执行完毕而产生/回收,是第二个被加载的名称空间,文件执行过程中产生的名字都会存放于该名称空间中,如下名字

        x = 10
        y = 20
        if 1 > 0:
            z = 30
        with open('a.txt', mode='wt') as f:
            a = 333
    
        while True:
            c = 444
    
    

    3、局部名称空间

    伴随函数的调用/结束而临时产生/回收,函数的形参、函数内定义的名字都会被存放于该名称空间中

        x = 10
        def foo(m):
            # m = 111
            n=222
        # foo(111)
    
    

    核心:再次强调!

    名称空间的加载顺序是:内置名称空间->全局名称空间->局部名称空间,而查找一个名字,必须从三个名称空间之一找到,查找顺序为:局部名称空间->全局名称空间->内置名称空间。

    作用域

    全局作用域:内置名称空间+全局名空间

    特点:全局存活,全局有效

    局部作用域:局部名称空间

    特点:临时存活,局部有效

    LEGB

    LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
    locals 是函数内的名字空间,包括局部变量和形参
    enclosing 外部嵌套函数的名字空间(闭包中常见)
    globals 全局变量,函数定义所在模块的名字空间
    builtins 内置模块的名字空间
    

    全局作用域

    全局作用域:位于全局名称空间、内建名称空间中的名字属于全局范围,该范围内的名字全局存活(除非被删除,否则在整个文件执行过程中存活)、全局有效(在任意位置都可以使用);

    局部作用域

    局部作用域:位于局部名称空间中的名字属于局部范围。该范围内的名字临时存活(即在函数调用时临时生成,函数调用结束后就释放)、局部有效(只能在函数内使用)。

    global

    #global
    # 案例1
    # l = []   # 当全局变量是一个可变类型  可以从局部空间改变
    # def func():
    #     # l.append(1111)
    #     ####  如果用global就能改  记住改是针对可变类型和重新定义不同
    #     l = [11,22,33]   #这样相当于在局部新定义一个变量
    #
    # func()
    # print(l)
    
    # 案例2:
    # x=111
    # def func():   #无法在局部空间更改全局的不可变类型变量
    #
    #     x =222
    # func()
    # print(x)    #>>>111
    
    #用 global 改
    # x=111
    # def func():
    #     global x  #  改全局变量  声明
    #     x =222
    # func()
    # print(x)   #>>>222
    

    nonlocal

    # nonlocal
    #  只会在函数里面外层 不会去全局查找
    x = 111
    def f1():
        x = 222
        def f2():
    
            nonlocal x  # 改外层函数  不会到全局
            x =333
    
        f2()
        print(x)  # 这是打印的222  现在想把他内层33改为22
    f1()
    

    闭包函数

    闭包函数的含义:

    # 闭包函数
    # 闭:指的是该函数是定义在函数内的函数
    # 包:指的就是该函数引用了e层函数作用域的函数
    

    闭包函数的定义:

    def outter():
        x = 111
        def wrapper():
            print(x)
    
        return wrapper # 千万别加()
    

    如何给函数传参?

    # 方案一:直接用参数传
    # def wrapper(x):
    #     print(x)
    # wrapper(111)
    # wrapper(222)
    # wrapper(333)
    
    #方案二:闭包函数
    # def outter (x):
    #     def wrapper():
    #         print(x)
    #     return wrapper
    # f1=outter(11111)
    # f1()
    #
    # f2=outter(222)
    # f2()
    
  • 相关阅读:
    Beta冲刺 第二天
    Beta冲刺 第一天
    实验十一 团队项目设计完善&编码测试
    实验十 软件系统详细设计与概要设计的改进
    实验九 FBG 团队项目需求改进与系统设计
    实验八 <FBG> 基于原型的团队项目需求调研与分析
    实验七 《FBG》—-小学生课后习题答案原型设计
    实验五 <FBG>团队亮相
    Windows zip版本安装MySQL
    redis安装与简单实用
  • 原文地址:https://www.cnblogs.com/cnblogswilliam/p/14206990.html
Copyright © 2020-2023  润新知