• 从函数对象到名称空间与作用域


    函数对象

    函数(Function)作为程序语言中不可或缺的一部分。

    在 Python 中万物皆为对象,函数也不例外,函数作为对象可以赋值给一个变量、可以作为元素添加到集合对象中、可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性就是第一类对象所特有的。

    函数拥有对象的三个通用属性:值、id、类型

    def pr_Hi():
        print('Hello World!')
    
    print(id(foo))  # 21301264
    print(type(foo))  # <class 'function'>
    print(foo)  # <function pr_Hi at 0x01450810>
    

    函数可以被引用

    def pr_Hi():
        print('Hello World!')
    
    pr_Hi2 = pr_Hi    #引用,赋值
    print(pr_Hi2)  # <function pr_Hi at 0x03020810>
    print(pr_Hi)  #<function pr_Hi at 0x03020810>
    pr_Hi2()  # Hello World!
    

    函数可以放入容器类数据类型

    容器对象(list、dict、set等)中可以存放任何对象,函数也可以作存放到容器对象中

    def pr_Hi():
        print('from pr_Hi')
    dic={'func':pr_Hi}
    
    pr_Hi()  # from pr_Hi
    
    print(dic['func'])  # <function pr_Hi at 0x00BE0810>
    
    dic['func']()  # from pr_Hi
    

    函数还可以当做参数

    def pr_Hi():
        print('from pr_Hi')  # from pr_Hi
    
    def bar(func):  ##执行函数
        print(func)  # <function pr_Hi at 0x014E0810>
        func()  ##调用上面地址的函数
    
    bar(pr_Hi)  ##第一步,先调用bar()函数
    

    函数可以作为返回值

    def pr_Hi():
        print('from pr_Hi')
    
    def bar(func):
        return func     
    
    f=bar(pr_Hi)
    
    print(f)  # <function pr_Hi at 0x00CA0810>
    
    f()  # from pr_Hi
    

    函数还可以嵌套

    def f1():
        def f2():
            print('from f2')
        return f2
    
    abc = f1()  # f1()拿到函数的返回值,函数的返回值是f2, abc就相当于f2
    abc()  # from f2
    

    匿名函数

    python 使用 lambda 来创建匿名函数。

    所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。

    • lambda 只是一个表达式,函数体比 def 简单很多。
    • lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
    • lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
    • 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。

    语法

    lambda [arg1 [,arg2,.....argn]]:expression

    例如

    sum = lambda arg1, arg2: arg1 + arg2
     
    # 调用sum函数
    print ("相加后的值为 : ", sum( 10, 20 ))  # 30
    print ("相加后的值为 : ", sum( 20, 20 ))  # 40
    
    ## 这样就是一个逻辑简单的匿名函数了,不过匿名函数一般不这么使用
    

    匿名函数的用法

    匿名函数一般和内置函数一起使用,例如:sort,sorted一起使用

    lt = [('a', 3000), ('i', 2600), ('o', 15000), ('d', 6500), ('p', 3000)]
    lt.sort()
    print(lt) # [('a', 3000), ('d', 6500), ('i', 2600), ('o', 15000), ('p', 3000)]
    ##这样只能让列表里面的元祖以元祖的第一个元素进行排序
    ##所以我们需要自己定义一个规则来进行排序
    def abc(i):   ##你们千万不要学我,我实在想不出来用什么好,就随便使用了
        return i[1]
    
    lt = [('a', 3000), ('i', 2600), ('o', 15000), ('d', 6500), ('p', 3000)]
    lt.sort(key=abc)  ## 可以通过他的key来改变它排序的规则
    print(lt)  # [('i', 2600), ('a', 3000), ('p', 3000), ('d', 6500), ('o', 15000)]
    ## 发现使用函数想不出函数名这个比较尴尬,还是使用匿名函数好些
    lt = [('a', 3000), ('i', 2600), ('o', 15000), ('d', 6500), ('p', 3000)]
    lt.sort(key=abc)  ## 可以通过他的key来改变它排序的规则,这样就可以不用考虑函数名
    print(lt)  # [('i', 2600), ('a', 3000), ('p', 3000), ('d', 6500), ('o', 15000)]
    
    

    函数空间与作用域

    一扯到函数的嵌套就不由自主的要开始扯函数空间与作用域了。

    函数空间:存放名字的地方,准确的说名称空间是存放名字与变量值绑定关系的地方

    • 内置名称空间:python自带的名字,在python解释器启动时产生,存放一些python内置的名字
    • 全局名称空间:在执行文件时,存放文件级别定义的名字
    • 局部名称空间:在执行文件的过程中,如果调用了函数,则会产生该函数的名称空间,用来存放该函数内定义的名字,该名字在函数调用时生效,调用结束后失效

    名称空间的顺序

    • 加载顺序:内置名称空间 --> 全局名称空间 --> 局部名称空间
    • 查找顺序:局部名称空间 --> 全局名称空间 --> 内置名称空间

    作用域: 产生作用的范围

    • 全局作用域:全局存活,全局有效
    • 局部作用域:局部存活,局部有效
    x = 1
    
    def f2():
        x = 2  # x=2只能在f2中使用
        print(x)
        
    print(x)  # 1
    f2()  # 2
    

    如果实在要改变全局的变量或者是局部的变量

    改全局名称
    x = 1
    def f1():
        global x
        x = 2
    f1()
    print(x)  # 2
    
    改局部名称
    x = 0
    def f1():
        x = 1
        def f2():
            x = 2
            def f3():
                nonlocal x #改的是函数正上方的值
                x = 3
                print('f3',x)  # f3 3
            f3()
            print('f2',x)  # f2 3
        f2()
        print('f1',x)  # f1 1
    print(x)  # 0
    f1()
    
    推荐使用引用类型
    lt = [1,2,3]  # 作用域关系仅适用不可变数据类型,不适用于可变数据类型
    def f1():
        lt.append(4)
    print(lt)  # [1, 2, 3]
    f1()
    print(lt)  # [1, 2, 3, 4]
    
  • 相关阅读:
    php注册、登录界面的制作
    php将表单中数据传入到数据库
    数据操作
    Hibernate入门(五)---------事务管理
    MySQL事务(学习笔记)
    Hibernate入门(四)---------一级缓存
    Hibernate入门(三)
    反射demo(拷贝一个对象)
    反射学习小结
    Hibernate入门(二)——hibernateAPI详解
  • 原文地址:https://www.cnblogs.com/Gredae/p/11329301.html
Copyright © 2020-2023  润新知