• 函数对象


    Python-12

    @(Python)

    一、函数对象

    • 函数是第一类对象,意思是函数可以被当做数据处理
    • 函数对象:就是函数不带括号
    • 函数对象,可以将定义在函数内的函数,通过return返回值,返回到全局中使用,从而打破函数的层级限制
    • Python中一切皆对象

    funcfunc()的区别

    • func()是函数的返回值
    • func函数名记录了值的内存地址(记录了值的内存地址,相当于连接函数名和值的线),函数名就是函数的内存地址
    • print(func)打印的是func函数名记录的值的内存地址
    • print(func())打印的是func函数的返回值

    Alt text

    ① 函数名可以被用来引用(赋值给一个变量)

    # func是一个函数
    y=x
    f=func
    print(f)   # 就相当于print(func)
    f()   # f()就相当于func()调用函数
    

    ② 函数名当做参数传给一个函数

    Alt text

    ③ 函数名可以当做函数的返回值

    Alt text

    ④ 函数名可以当做容器类型的元素

    可以把函数的内存地址(或理解为函数名的内存地址),当做元素

    Alt text

    利用函数名为容器类型的元素,来调用函数

    # 取款
    def qk():
        print('取款成功')
    
    # 转账
    def zz():
        print('转账成功')
    # 支付
    def zf():
        print('支付成功')
    
    
    func_dict={
        '1':qk,
        '2':zz,
        '3':zf,
    }
    
    while True:
        msg='''
        1. 取款
        2. 转账
        3. 支付
        4. 退出   
        '''
        print(msg)
        func_num=input('输入数字>>')
        if func_num == '4' : break
        if func_num not in func_dict:
            print('不在范围')
            continue
        func_dict[func_num]()
    

    二、函数的嵌套

    1. 函数的嵌套定义

    • 函数的嵌套是在函数中再定义函数
    • 在函数内中定义的函数,只能在这个函数内使用(一般情况下)
    def func1():
        def func2():
            print('函数2')
    
    • 通过函数嵌套,将一个大功能的小功能嵌套进去,不同的功能汇聚到一起,类似于封装成一个工具箱
    • 例子:利用函数嵌套和函数对象当做容器元素,来写出计算圆面积和周长的功能
    from math import pi    # 计算圆的公式需要调用
    def yuan(banjing,action):
        def mianji():
            return pi * (banjing ** 2)
        def zhouc():
            return pi * banjing * 2
        if action == 'mianji':
            return mianji()    # 这是yun函数的返回值
        elif action == 'zhouc':
            return zhouc()
    
    func1=input('半径>>')
    func1=int(func1)
    func2=input('计算类型>>')
    
    print(yuan(func1,func2))   # 也可以使用默认形参固定一个常用的类型
    

    2. 函数的嵌套调用

    • 使用函数嵌套,在调用一个函数时,也调用了其他函数
    • 如果一个功能可以被重复调用,就可以单独做成一个功能,使用其他函数再调用

    Alt text

    三、名称空间与作用域

    1. 名称空间

    • 专门用来存名字的空间(变量名、函数名等的内存地址)
    • 名称空间,是存放名字和值绑定关系的地方

    ① 内置名称空间

    • 内置命名空间:Python解释器自带的名字
    • 生命周期:在解释器启动时生效,在解释器关闭时失效

    ② 全局名称空间

    • 全局名称空间:除了内置和局部空间外,其余都是全局名称空间
    • 全局名称空间,是在文件执行时产生的(顶头写的代码使用的就是全局名称空间)
    • 生命周期:在文件执行时生效,在文件执行完毕后失效

    ③ 局部名称空间

    • 存放函数调用期间函数体产生的名字,即函数内定义的名字
    • 生命周期:执行文件时,只有被调用了才会临时生效,在函数执行完毕后失效,自动释放

    内置、全局、局部名称空间的加载顺序

    • ① 内置名称空间--->② 全局名称空间--->③ 局部名称空间

    内置、全局、局部名称空间的查找顺序

    • ① 局部名称空间--->② 全局名称空间--->③ 内置名称空间
    • 基于当前位置,然后按顺序找

    Alt text
    Alt text

    2. 作用域

    • 作用域就是名称空间的作用的范围,是对名称空间的再分类

    ① 全局作用域

    • 全局作用域:就是全局作用范围,包括:内置名称空间和全局名称空间
    • 全局有效:内置命名空间和全局命名空间
    • 全局存活:从程序开始存活,一直到程序的结束

    ② 局部作用域

    • 局部作用域:就是局部作用范围,包括:局部命名空间
    • 局部有效,临时存活

    • 作用域关系是在函数定义阶段就固定好了,但凡要调用函数就需要去函数的定义阶段找作用域关系

    Alt text

    x=10
    def func1():
        print(x)
    
    x=10000000000000000000000
    def func2():
        x=11111111111
        func1()
    
    func2()   # 以调用为分隔符,往前找
    

    Alt text

    Alt text

    x=10
    def func1():
        x=777777777777777777  # 先找局部空间,再找全局空间,全局空间有多个找上面最近的
        print(x)
    
    x=10000000000000000000000
    def func2():
        x=11111111111
        func1()
    
    func2()   # 以调用为分隔符,往前找
    

    ③ 作用域的应用:

    • 打破层级限制,利用return将函数名转到全局,再调用

    Alt text
    Alt text

    def f1():
        def inner():
            print('from inner')
        return inner
    
    f1()() # f1()得到的是return的值,相当于inner,f1()() == inner()
    
    # 或者
    
    f=f1()
    f()   # 相当于f1()()
    

    Alt text

    def f1():
        x=1
        def inner():
            print('from inner',x)
        return inner
    
    f=f1()   # 相当于f=inter
    
    def bar():
        x=11111111111111
        f()   # 相当于inter()
    
    bar()
    
    • 说明:回到定义阶段,按照先局部,后全局的顺序找,如果局部没有才找全局,如果有多个全局,就以调用函数为分隔线,往上找最近的

    • 在函数体内,改全局的东西,需要使用global x,比如global xx拿到全局用,同代码段往下找最后一个
    • 但是尽量不要改全局,尽量做成独立的功能,对其他无影响
    x=1
    def foo():
        global x
        x=111
    
    foo()
    print(x)
    
    • nonlocal会往本函数体外层找,往上找最近的,但是还是在大的函数内,找到就改,找不到就报错
    x=1
    def f1():
        def f2():
            x=2222222            # 找到的内容
            def f3():
                nonlocal x
                x=111111111111   # 要改成什么
            f3()
            print(x)   # 打印这一层的,看nonlocal是后生效
        f2()
    
    f1()
    

    Alt text

    • 在局部如果想要修改全局的可变类型,不需要借助任何声明,可以直接修改,比如可以改字典,列表等
    • 在局部如果想要修改全局的不可变类型,需要借助global声明,声明为全局的变量就可以直接修改

    Alt text

  • 相关阅读:
    莫队模板
    CF600E Lomsat gelral
    JZOJ 捕老鼠
    JZOJ 4896. 【NOIP2016提高A组集训第16场11.15】兔子
    JZOJ 4895【NOIP2016提高A组集训第16场11.15】三部曲
    双端队列xLIS问题
    最大K段和
    你真的了解ES6的promise吗?
    JS对象和数组深浅拷贝总结②
    当前页码删除唯一数据后加载前一页内容
  • 原文地址:https://www.cnblogs.com/itone/p/9443649.html
Copyright © 2020-2023  润新知