美文网首页
python高阶函数

python高阶函数

作者: 柒轩轩轩轩 | 来源:发表于2021-05-21 23:52 被阅读0次

    把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式

    map/reduce

    我们先看map。map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。

    def f(x):
        return x*x
    r = map(f, [1,2,3,4])
    print(list(r)) # [1,4,9,16]
    

    再看reduce的用法。reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算
    reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

    filter

    和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素
    注意到filter()函数返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list。

    sorted

    sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序

    sorted([36, 5, -12, 9, -21], key=abs)
    

    函数作为返回值

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

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

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

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

    闭包

    def count():
        fs = []
        for i in range(1, 4):
            def f():
                 return i*i
            fs.append(f)
        return fs
    
    f1, f2, f3 = count()
    

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

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

    如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:

    def count():
        def f(j):
            def g():
                return j*j
            return g
        fs = []
        for i in range(1, 4):
            fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
        return fs
    

    装饰器

    本质上,decorator就是一个返回函数的高阶函数。所以,我们要定义一个能打印日志的decorator

    import functools
    def log(func):
        @functools.wraps(func)
        def wrapper(*arg,**kw):
            print('call %s',%func.__name__)
            return func(*arg, **kw)
        return wrapper
    
    @log
    def now():
        print('2015-3-25')
    

    如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,写出来会更复杂。比如,要自定义log的文本

    import functools
    def log(text):
        def decorator(func):
            @functools.wraps(func)
            def wrapper(*args, **kw):
                print('%s %s():' % (text, func.__name__))
                return func(*args, **kw)
            return wrapper
        return decorator
    
    @log('execute')
    def now():
        print('2015-3-25')
    

    相关文章

      网友评论

          本文标题:python高阶函数

          本文链接:https://www.haomeiwen.com/subject/abuijltx.html