python一等函数与高阶函数


目录
  • 什么是一等对象?
  • python中的一等对象
  • 高阶函数与函数式编程
    • 高阶函数定义
    • 函数式编程
    • 常见高阶函数
  • 函数内省
  • 函数传参四种形式
    • 定位参数
    • 关键字参数
    • 可变参数
    • 仅限关键字参数
  • 函数参数注解
  • 支持函数式编程的包
    • operator模块
    • functools.partial

什么是一等对象?

  • 满足下列条件的为一等对象:
    • 在运行时创建
    • 能复制给变量或数据结构中的元素
    • 能作为参数传递给函数
    • 能作为函数的返回结果

python中的一等对象

  • 整数、字符串、字典等都是一等对象。
  • 所有的函数都是一等对象,有时简称为一等函数,但是要注意并没有二等三等函数的说法。
  • 函数对象都属于类function

高阶函数与函数式编程

高阶函数定义

  • 所谓高阶函数,就是以函数为参数,或者把函数作为结果返回的函数。比如内置的sorted()函数,其参数key即为一个函数,可以应用到每一个元素上进行排序依赖指标计算。

函数式编程

  • 函数式编程的特点之一即为使用高阶函数

常见高阶函数

  • map内置函数
    • 用法格式为 map(func, seq),其中seq是一种序列型对象
    • map把func一次应用到seq中的每个元素上,返回一个生成器
  • filter内置函数
    • 用法格式与map一样,filter(func, seq),seq是一种序列型对象
    • 区别是filter中的第一个参数func返回值是布尔值,把func应用到seq中的每个元素上,如果使得返回结果为True,则保留该元素,否则将该元素滤除,返回所有保留元素的生成器
  • reduce,functools模块中的函数
    • 江湖人称归约函数,用法格式为reduce(func, seq),seq是序列型对象
    • 首先将seq中前两个元素用于func,得到返回值,然后将返回值和seq第三个元素一起传入func,再得到返回值......,以此类推,不断累积之前的结果,知道把一个序列的值规归约成一个值。
  • all,内置规约函数
    • all(itetable),若iterable中每个元素都为真,则返回True
  • any,内置规约函数
    • any(iterable),只要iterable中有元素是真值,就返回True

函数内省

  • 函数内省即获取函数自身的性质
  • dir()函数可以获取函数的属性列表,用法格式为dir(func),返回值是一个列表
  • python函数对象__defaults__属性,保存定位参数和关键字参数的默认值
  • python函数对象__kwdefaults__属性,保存仅限关键字参数默认值
  • python函数对象__code__属性中,code.co_argcount保存参数数目,code.co_varnames保存参数名称
  • inspect模块中的signature函数进行函数内省
    from inspect import signature
     
    def ppp(c = 1, e = 1, *, a, b = 3):
        print(a, b)
    sig = signature(ppp) # 获取ppp函数的签名,其实就是ppp函数的一些元信息
    print(sig)
    print(type(sig.parameters))
    for name, param in sig.parameters.items():
        print(param.kind, name, '=', param.name, '=', param.default)
    
    
    • 输出为:
    (c=1, e=1, *, a, b=3)
    
    POSITIONAL_OR_KEYWORD c = c = 1
    POSITIONAL_OR_KEYWORD e = e = 1
    KEYWORD_ONLY a = a = 
    KEYWORD_ONLY b = b = 3
    
    

函数传参四种形式

定位参数

  • 按照实参的位置依次传给形参,如果形参有缺省值,那么该形参要在形参列表的最后边。

关键字参数

  • 函数调用传参的时候手动列出形参名,比如add(a=1, b=2),而不是用定位传参的add(1, 2)

可变参数

  • 指的是传入任意个数的参数
  • *标识在形参上,用于传入任意个数的定位实参,即把多余的定位实参以元组的形式传给*标识的形参。
  • **标识在形参上,用于传入任意个数的关键字实参,即把多余的关键字实参以字典的形式传入**标识的形参。

仅限关键字参数

  • 即只能通过关键字传参
  • 定义仅限关键字参数只需要将该形参a放在可变参数*后边,这样不断有多少定位实参都会被*标识的形参捕捉到,而不会传给该形参a。
  • 如果不想要*标识形参捕捉到的信息,则可以不写形参名,只写一个*号,如下例子:

函数参数注解

  • 即在形参列表中,形参后边加个冒号,然后跟上注解表达式
  • 如果参数有默认值,注解放在形参和=之间。
  • 如果要注解返回值,可以用 -> 后跟上注解表达式
  • 注解表达式可以是任意类型

支持函数式编程的包

operator模块

  • 提供常用的加减乘除等操作

functools.partial

  • partial高阶函数用于部分应用一个函数,相当于对某个函数进行改造,比如一个两个参数的函数,给其中一个参数提供默认值,改造成只需要一个参数的函数。
  • partial用法为第一个参数传入一个可调用对象,后边跟任意个提供默认值的定位参数和关键字参数
  • partialmethod函数跟partial用法一样,只是用于处理方法