zoukankan      html  css  js  c++  java
  • 进阶函数

    一、函数对象

    函数是第一类对象:函数名指向的值可以被当做参数传递

    1.函数名可以被传递

    def func():
        print('func')
    
    f = func  # 函数名可以当做变量名
    print(f)  # f指向的也是函数func指向函数体代码的内存地址

    2.函数名可以被当做参数传递给其他参数

    def func():
        print('from func')
    
    def index(args):
        print(args)
        args()  # from func
        print('from index')
    index(func)  #把func这个函数名传递给args,打印出来的结果为:<function func at 0x0000028A85681F28>
                 #from index

    3.函数名可以被当作函数的返回值

    def index():
        print('index')
    
    
    def func():
        print('func')
        return index
    res = func()  # func
    print(res)  # 函数名的内存地址:<function index at 0x000001E573521F28>
    res()  # 返回值:index

    4.函数名可以被当作容器类型的参数

    def func():
        print('func')  # func
    print(func())  # None
    l = [1,2,func,func()]  # func  
    print(l)  # [1,2,<function func at 0x000001F7D79899D8>,None

    二、函数嵌套

    1.函数嵌套的调用

    在函数内部调用其他函数
    可以将复杂的逻辑简单化

    # def max2(x,y):
    #     if x > y:
    #         return x
    #     else:
    #         return y
    
    # def max3(x,y,z):
    #     res1=max2(x,y)  # 先比较x和y的值
    #     res2=max2(res1,z)  # 较大的值与z进行比较
    #     return res2  # 返回较大的值
    # print(max3(7,8,9))

    2.函数嵌套的定义

    def outer():
        x = 1
        print('outer')
        def inner():
            print('inner')
        # print(inner)
        return inner
    
    res = outer()  # outer
    print(res)  # <function outer.<locals>.inner at 0x000001F19F822AE8>
    res()  # inner

    三、名称空间

    存放的是变量名与变量值的内存地址的绑定关系的地方

    想要访问一个变量的值,必须先去名称空间拿到对应的名字,才能够访问变量的值

    1.名称空间的分类

    1》内置名称空间:python解释器提前给你定义好的名字(已经存放在内置名称空间),如len,max

    2》全局名称空间:文件级别的代码(if for while 无论嵌套多少层,它们内部所创建的名字都是全局名称空间)

    3》局部名称空间:函数体内创建的名字都属于局部名称空间

     

    2.生命周期

    内部名称空间:只要python解释器已启动立马创建,关闭python解释器的时候内置名称空间自动销毁

    全局名称空间:只要右键运行py文件会自动创建,py文件程序运行结束自动销毁

    局部名称空间:函数调用的时候自动创建,函数指向结束立即销毁(动态创建动态销毁)

    3.名字查找的顺序

    1》站在全局的角度:全局>内置

    2》站在局部的角度:局部>全局>内置

    x = 1
    def f1():
        x = 2
        def f2():
            x = 3
            def f3():
                x = 4
                def f4:
                    x = 5
                    print(x)
                f4()
            f3()
        f2()
    f1()
    
    #当需要调用f1的时候,会站在f4的局部去取值,如果f4没值就会取f3的值,按照局部>全局>内置这个顺序去取值

    注意:

    函数在定义阶段查找名字的顺序就已经固定了 不会因为函数的调用位置变化

    四、作用域

    1.全局作用域

                        全局有效:内置名称空间  全局名称空间

    2.局部作用域

                       局部有效 : 局部名称空间

    3.glolal

    在局部修改全局的变量,如果需要修改多个,用逗号隔开

    x = 1
    
    def func():
        x = 2
    func()
    print(x)  # 1
    
    #首先,调用函数func在全局名称空间,所以要站在全局名称空间这个角度去看,就不需要考虑
    #局部名称空间了,全局有 x = 1 这个数,所以打印结果就为1
    
    
    
    #如果就要将打印结果变为局部 x = 2这个数呢?该怎么操作?
    x = 1
    
    def func():
        global x  # 在局部修改全局的变量
        x = 2
    func()
    print(x)  # 2

    4.nonlocal

    在局部修改局部的变量,如果想修改多个,用逗号隔开

    def func():
        x = 1
        def index():
            nonlocal x  # 局部修改局部
            x = 2
        index()
        print(x)
    func()  # 2
  • 相关阅读:
    JSDI——实现数据库连接池(JDBC改进)
    MD5加密算法(实际应用)
    Java Web 自动登录
    异步编程设计模式Demo
    异步编程设计模式Demo
    禁止程序启动2次
    C#线程同步的几种方法
    ASP.NET MVC的Action Filter
    带有返回值的intent
    android 属性动画
  • 原文地址:https://www.cnblogs.com/xiongying4/p/11165234.html
Copyright © 2011-2022 走看看