zoukankan      html  css  js  c++  java
  • 高阶函数

    --------------以下部分摘自马哥教育

    函数的一般形式:

      y= f(x)

    x成为自变量,y是x的函数 (域值)

    高阶函数:

      y=f(g(x))

    定义:

      接受一个或者多个函数作为参数

      返回一个函数

    def counter(base):
        def inc(step=1):
            nonlocal base
            base += step
            return base
    
        return inc
    
    
    foo = counter(5)
    print(foo())
    f1 = counter(5)
    f2 = counter(5)
    print(id(f1), id(f2), id(foo))

    因为上面例子中,返回的是一个函数,即可以看成返回的是一个对象,所以在调用时,尽管参数值一样,但是,不同的调用产生了不同的对象,存放的地址是不一样的。

    高阶函数的用途:

      函数作为返回值,往往会形成闭包;

      函数作为参数,应用很广泛。

    排序问题举例:

    lst = [2, 4, 6, 8, 4, 6, 3, 2, 4, 5]
    
    
    def sort(lis, fn=lambda a, b: a < b):
        def compare(a, b):
            return a < b if asc else a > b
    
        newlst = []
        for x in lst:
            for i, y in enumerate(newlst):
    
                if fn(x, y):
                    newlst.insert(i, x)
                    break
            else:
                newlst.append(x)
    
        return newlst
    
    
    print(sort(lst))
    print(sort(lst, lambda x, y: x < y))
    print(sorted(lst, reverse=True))  # sorted 排序函数
    print(list(map(lambda x: (x, x + 1), lst)))  # map 映射函数
    print(list(filter(lambda x: x > 3, lst)))  # filter 过滤函数

    上面例子中我们把逻辑抽象成一个函数,然后有外部作为参数传入,大大增加编程的灵活性。

    柯里化

      定义:指的是将原来接受两个参数函数的函数变成新的接受一个参数的函数的过程,新的函数返回一个以原有第二个参数为参数的函数

      数学表示:z=f(x,y)转换成z=f(x)(y)

    举例:

    def add(x, y):
        return x + y
    
    
    print(add(4, 5)) # z=f(x,y)
    
    
    def new_add(x):
        def inner(y):
            return x + y
    
        return inner
    
    
    print(new_add(4)(5)) # z=f(x)(y)

    装饰器

      装饰器是一个高阶函数-------函数作为返回值,函数作为参数。

      定义:装饰器就是一个函数,它接受一个业务函数作为参数,返回一个包装函数,而包装函数里面包装了(闭包了)原有的业务函数。

      作用:对原有的业务函数在外围进行业务增强,而不用写过多的侵入式代码侵入到原有业务函数的核心业务,结果就是增强了原有业务函数的纯净性和可读行。

    举例:

    import datetime
    import time
    
    
    def logger(fn):  # fn = add,add传入的是fn
        def wrapper(*args, **kwargs):  # 定义可变参数和可变关键字参数;在这个例子中,变量add指向了装饰器函数,从而使wrapper函数有了参数
            # before
            print('args = {} , kwargs = {}'.format(args, kwargs))  # 功能增强
            start = datetime.datetime.now()
    
            ret = fn(*args, **kwargs)  # 解构可变参数和关键字参数,还原了业务函数add
            # after
            print(ret)
            delat = (datetime.datetime.now() - start).total_seconds()
            if delat > 2:
                print("{} took {}S".format(fn.__name__, delat))
    
            else:
                print("so fast")
            return ret  # 返回的add函数的原型,保证add函数原有内容,防止返回NONE值。
        return wrapper  # 返回的warpper是增强版本的add函数
    
    
    @logger  # 相当于 add = logger(add)而等号左边的add相当于指向了函数warpper ,而@是语法糖
    def add(x, y):
        time.sleep(3)
        return x + y
    
    
    # add = logger(add)  # return warp ,warp = 增强版的fn
    print(add(4, y=6))

    装饰器相当于一个语法糖,让原业务代码看起来更加有业务性,美化了写法,让别人更容易懂。

  • 相关阅读:
    spring入门-day01
    HTML概述
    day21-基础加强
    iptables
    25个iptables常用示例
    Linux安全调优1:CentOS防火墙的设置与优化
    sessionStorage 的数据会在同一网站的多个标签页之间共享吗?这取决于标签页如何打开
    JavaScript reduce() 方法
    classList属性和className的区别
    NPM 学习笔记整理
  • 原文地址:https://www.cnblogs.com/jameskane/p/8671810.html
Copyright © 2011-2022 走看看