zoukankan      html  css  js  c++  java
  • Python自动化开发

    本节内容

    一、函数式编程

    二、高阶函数

      1、变量可以指向函数

      2、函数名也是变量

      3、传入函数

    三、返回函数

      1、函数作为返回值

      2、闭包特性

    一、函数式编程

    函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,

    这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元

    我们首先要搞明白计算机(Computer)和计算(Compute)的概念。

    在计算机的层次上,CPU执行的是加减乘除的指令代码,以及各种条件判断和跳转指令,所以,汇编语言是最贴近计算机的语言。

    而计算则指数学意义上的计算,越是抽象的计算,离计算机硬件越远。

    对应到编程语言,就是越低级的语言,越贴近计算机,抽象程度低,执行效率高,比如C语言;

    越高级的语言,越贴近计算,抽象程度高,执行效率低,比如Lisp语言。

    函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,

    因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用

    而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的

    函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数

    Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。

    二、高阶函数

    高阶函数 Higher-order function

    1、变量可以指向函数

    print(abs(-10))  # 调用绝对值函数
    print(abs)       # 函数本身
    
    x = abs(-10)     # 函数返回值 10 赋给变量 x,
    
    f = abs          # 函数本身赋值给变量 f ,即变量可以指向函数
    print(f(-10))    # 输出结果为 10
    
    # 说明变量 f 已经指向了abs函数本身。直接调用abs()函数和调用变量f()完全相同

    2、函数名也是变量

    函数名其实就是指向函数的变量!对于abs()这个函数,完全可以把函数名abs看成变量,它指向一个可以计算绝对值的函数

    abs = 10
    
    print(abs)       # 输出结果  10
    print(abs(-10))  # 错误信息 TypeError: 'int' object is not callable
    

     abs指向10后,就无法通过abs(-10)调用该函数了!因为abs这个变量已经不指向求绝对值函数而是指向一个整数10!

    3、传入函数

    既然变量可以指向函数,函数的参数能就收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数

    def add(x, y, f):
        return f(x) + f(y)
    
    add_sum = add(-10, 10, abs)  # x=-10 y=10 f=abs
    print(add_sum)
    

    编写高阶函数,就是让函数的参数能够接收别的函数

    三、返回函数

    1、函数作为返回值

    高阶函数除了可以接收函数作为参数外,还可以把函数作为结果值返回。

    实现一个可变参数的求和。通常情况下,求和的参数是这样定义的:

    def calc_sum(*args):
        ax = 0
        for n in args:
            ax += n
        return ax
    

    但是,如果不立刻求和,而是在后面的代码中,根据需要再计算,所以可以不返回求和的结果,而是返回求和的函数:

    def lazy_sum(*args):
        def inner_sum():
            ax = 0
            for n in args:
                ax += n
            return ax
        return inner_sum    # 定义时,返回相应函数
    
    f1 = lazy_sum(1, 3, 5, 7, 9)  # 调用函数lazy_sum,返回值为函数inner_sum
    f2 = lazy_sum(1, 3, 5, 7, 9)  # 调用函数lazy_sum,返回值为函数inner_sum
    
    print(f1)        # <function lazy_sum.<locals>.inner_sum at 0x000000B2C801C510>,返回值为函数 inner_sum
    print(f1 == f2)  # False, 说明 f1和f2是独立的
    
    print(f1())      # 调用函数f1,返回值为求和结果
    print(f2())      # 调用函数f2,返回值为求和结果
    

    在这个例子中,我们在函数lazy_sum中又定义了函数calc_sum,并且,内部函数calc_sum可以引用外部函数lazy_sum的参数和局部变量,

    lazy_sum返回函数calc_sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。

    请再注意一点,当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数。

    2、闭包特性

    注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用

    闭包用起来简单,实现起来可不容易。

    另一个需要注意的问题是,返回的函数并没有立刻执行,而是直到调用了f()才执行。我们来看一个例子:

    def count():
        fs = []
        for i in range(1, 4):
            def func():
                return i*i
            fs.append(func)  # 把函数名func,添加到列表fs
        return fs           # 返回值为列表
    
    print(count())  # 列表,其中元素为函数func
    f4, f5, f6 = count()    # 把列表元素依次赋给f4,f5,f6
    print("f4(): ", f4())  # 调用函数func(),返回 i*i,结果为9
    print("f5(): ", f4())  # 调用函数func(),返回 i*i,结果为9
    print("f4(): ", f4())  # 调用函数func(),返回 i*i,结果为9

    在上面的例子中,每次循环,都创建了一个新的函数,然后,把创建的3个函数都返回了,实际的返回结果都为9

    原因在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了9,因此最终结果都为9

    返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量

  • 相关阅读:
    ubuntu下安装maven
    159.Longest Substring with At Most Two Distinct Characters
    156.Binary Tree Upside Down
    155.Min Stack
    154.Find Minimum in Rotated Sorted Array II
    153.Find Minimum in Rotated Sorted Array
    152.Maximum Product Subarray
    151.Reverse Words in a String
    150.Evaluate Reverse Polish Notation
    149.Max Points on a Line
  • 原文地址:https://www.cnblogs.com/jonathan1314/p/6392712.html
Copyright © 2011-2022 走看看