• Python小白学习之路(十四)—【作用域】【匿名函数】【编程方法论】【高阶函数】


     

     

    吧啦吧啦内心戏
    在没有具体学作用域之前,我在之前的学习笔记中就有提到
    我开始以为是自己自创的词儿
    没想到这个词早已经存在(手动捂脸)
    真是个无知的小火锅(不知者无罪)
    我发现自己最擅长做的事情,就是给自己找个台阶,然后很快顺势滑下来


    一、作用域

    先来一段代码分析一波吧

     1 name = 'xhg'
     2 def name1():
     3     name = 'aa'
     4     def name2():
     5         name = 'bb'
     6         print(name)
     7     return name2
     8 a = name1()
     9 print(a)
    10 a()
    
      #执行结果
      <function name1.<locals>.name2 at 0x004D94B0>
      bb

    有很多人会有疑问,最后一行代码 a() 的作用域是第一层,我在之前的学习笔记中也是这么理解的
    既然他的作用域是第一层,则执行 print(name) 的时候,结果不应该是 xhg 吗?怎么是  bb
    原来我之前对作用域的理解有些误会

    '''
    #分析代码执行过程
    1.name = 'xhg' 定义全局变量
    2.def name1(): 定义了函数name1,在内存中开辟了空间,但函数内部具体内容不执行
    3.a = name1() 执行name1函数,并将其结果赋值给变量a
    4.name = 'aa' 定义了局部变量
    5.def name2(): 定义了函数nam2,在内存中开辟了空间,但函数内部具体内容不执行
    6.return name2 返回一个函数name2,则返回函数的执行结果,该结果为name2的内存地址,所以变量a的值为name2的内存地址
    7.a() 实质为执行函数name2
    8.name = 'bb' 定义了局部变量
    9.print(name) 在该作用域中找变量的值,所以打印结果为 bb
    '''

    结论:

    • 函数的运行与其申明定义的作用域有关,与其执行的作用域(调用的)无关
      • 函数一旦定义成功,其相对作用域已经确定
      • 所以在上一段程序代码中,a() 虽然和 name = 'xhg' 看上去为一个作用域,但实质上,a() 的作用域为函数 name2
    • return +函数名          返回的是该函数的内存地址
      • eg. renturn name1
    • return +函数名()        递归调用
      • eg. renturn name1()
    • 对于一个函数的执行结果其实就是return返回的值


    再看两段代码

    #代码一:
    name = 'xhg'
    def name1():
        name = 'aa'
        def name2():
            name = 'bb'
            def name3():
                name = 'cc'
                print(name)
            return name3
        return name2
    a = name1()
    b = a()
    print(b())
    
    #代码二:
    name = 'xhg'
    def name1():
        name = 'aa'
        def name2():
            name = 'bb'
            def name3():
                name = 'cc'
                print(name)
            return name3
        return name2
    print(name1()()())
    
    #执行结果相同,都为
    cc
    None

           说明     print(name1()()())   等同于   a = name1() ;b = a() ;print(b())


    二、匿名函数

    语法结构(由四部分构成)lambda关键字  +  匿名函数的形参 +  冒号:+  该函数的操作(子代码)

    • 第四部分的作用相当于return,直接返回了一个值
    • 不可以是复杂的逻辑判断,直接来个操作就ok了
    • 加载完之后释放,需要保存就附一个值
    • 匿名函数与其他函数联合使用,通常情况下不会单独存在


    关键字 lambda

    • 用来标识匿名函数
    def calc(x):
        return x + 1
    a = calc(10)
    print(a)

    用匿名函数来实现上述程序的功能

    a = lambda x : x + 1
    print(a(10))


    如果形参为多个参数,应该用括号将匿名函数的第四部分括起来
    (因为在使用return返回多个参数时,系统默认加了括号)

    def test(x,y,z):
        return x + 1, y + 1, z + 1
    a = test(1,2,3)
    print(a)
    
    用匿名函数来实现上述程序的功能

    a
    = lambda x, y, z : (x + 1, y + 1, z + 1) #如果不加括号会报错 print(a(1, 2, 3))


    三、编程的方法论

    有三种,分别是:面向过程编程、函数式编程、函数式编程

    面向过程编程

    • 是一种以事件为中心的编程思想。
    • 就是分析出解决问题的步骤,然后用方法(函数)去实现这些步骤
    • 使用的时候按照步骤顺序依次调用。
    • 面对要实现的功能,找到解决问题的入口,按照一个固定的流程去模拟解决问题的流程
    • 面向过程是一种自顶向下的编程


    函数式编程

    • 就是先定义一个数学函数,按照数学模型用编程语言去实现它

    举例:现在有这样一个数学表达式:y = 2 * x + 1

    #面向过程式的编程:
    def cal(x):
        a = 2 * x
        a += 1
        return a
    print(cal(10))
    
    #函数式编程:
    def cal(x):
        return 2 * x + 1
    print(cal(10))

    面向对象编程

    • 是一种线性的思维。
    • 与面向过程是相辅相成的。
    • 面向对象就是将构成问题的事务分解抽象成各个对象。
    • 建立对象的目的不是为了完成某个步骤,而是叙述某个事务在整个解决问题的步骤中的行为。
    • 面向对象是将事物高度抽象化。


    四、高阶函数

    定义(满足其中一个条件即可)

    • 函数接受的参数是一个函数名
    • 返回值中包含函数


    举例一:函数接受的参数是一个函数名

    def name1(n):      #n的值为函数name2的返回值none,所以不是高阶函数
        print(n)
    def name2(name):
        print('my name is %s' %name)
    name1(name2('xhg'))
    #执行结果
    my name is xhg
    None
     
     
    def name1(n):        #n的值为函数name2,所以是高阶函数
        print(n)
    def name2(name):
        print('my name is %s' %name)
    name1(name2)
    
    #执行结果
    <function name2 at 0x021594B0>

    举例二:返回值中包含函数

    def name1():
        print('from name1')
    def name2():
        print('from name2')
        return name1        #返回值中包含函数,所以为高阶函数
    n = name2()
    n()
    
    #执行结果
    from name2
    from name1
    
    def name1():
        print('from name1')
    def name2():
        print('from name2')
        return name1()       #递归调用
    n = name2()
    print(n)
    
    #执行结果
    from name2
    from name1
    None

    由于   return name1   和 return name1()   就差一个括号,导致结果不同
    虽然差别小,可是有本质的区别,要注意
    return name1 是将函数name1的地址赋值给n
    return name1() 必须先执行函数name1,将函数name1执行结束后的值由return返回给n(函数name无返回值,所以其结果为none)

    写在后面的话:

    今天下午有点累

    中午没有休息好

    长大以后,才发现一个人能做到换位思考真的不是很容易

    保持一颗善良的心看待这个世界

    因为抱怨会让自己变得消极

    全世界我最可爱(自己鼓励自己呗,开开心心才能好好学习)

  • 相关阅读:
    策略模式
    模板方法模式

    kafka
    Linux下部署MongoDB
    Linux下安装ssdb
    ssdb常用知识点
    Eclipse 的 Java Web 项目环境搭建
    PLSQL连接Oracle
    redis书籍
  • 原文地址:https://www.cnblogs.com/guoruxin/p/9923954.html
Copyright © 2020-2023  润新知