美文网首页
11.函数式编程:匿名函数、高阶函数、装饰器

11.函数式编程:匿名函数、高阶函数、装饰器

作者: tomtiddler | 来源:发表于2018-10-01 09:23 被阅读0次

    lambda表达式

    def add(x, y):
        return x + y
    
    print(add(1, 2))
    
    f = lambda x, y: x + y
    
    print(f(1, 2))
    

    匿名函数的简单使用。
    匿名函数最适合的场景是需要传入函数作为参数,返回值的操作不复杂的地方
    python对匿名函数的支持非常有限

    三元表达式

    表达式版本的if...else...
    其他语言的表达式x > y ? x : y
    python的表达式 x if x > y else y
    三元表达式经常用在lambda匿名函数中

    map

    list_x = [1, 2, 3, 4, 5, 6, 7, 8]
    
    def f1(x):
        return x * x
    
    list_y = map(f1, list_x)
    print(list_y)  # 生成的是惰性的序列
    print(list(list_y))
    

    map会对可迭代对象的每一项执行函数 f1 并返回新的可迭代对象

    map与lambda

    list_x = [1, 2, 3, 4, 5, 6, 7, 8]
    
    list_y = map(lambda x: x * x, list_x)
    print(list_y)  # 生成的是惰性的序列
    print(list(list_y))
    

    传入多个参数的map,将计算几个参数中长度最短的序列次数的映射(下例中为6次)

    # map
    
    list_x = [1, 2, 3, 4, 5, 6, 7, 8]
    list_y = [1, 2, 3, 4, 5, 6]
    
    r1 = map(lambda x: x * x, list_x)
    print(r1)  # 生成的是惰性的序列
    print(list(r1))
    
    r2 = map(lambda x, y: x + y, list_x, list_y)
    print(r2)
    print(list(r2))
    

    map 和 reduce 组合 能非常简单地构建一个字符串转换成整数的方法 ->

    from functools import reduce
    
    DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
    
    def char2num(s):
        return DIGITS[s]
    
    def str2int(s):
        return reduce(lambda x, y: x * 10 + y, map(char2num, s))
    

    reduce

    from functools import reduce
    
    list_x = [1, 2, 3, 4, 5, 6, 7, 8]
    
    r2 = reduce(lambda x, y: x + y, list_x)
    print(r2)
    

    reduce运算规则,连续计算,调用列表的第一个和第二个参数,通过传入的函数进行计算,返回值作为第一个参数,然后从列表读取第三个参数作为函数的第二个参数,再进行计算。。。直至参数调用结束。返回计算值。
    二维数组的累加(累积计算,本处为相加)
    reduce(func, param, initial) 函数、参数列表、初始值

    from functools import reduce
    
    move_list = [(1, 1), (-2, 1), (1, -3), (2, -4)]
    
    result = reduce(lambda x, y: (x[0] + y[0], x[1] + y[1]), move_list, (10, 10))
    
    print(result)
    

    大数据计算模型: map/reduce
    编程模型 map 映射 reduce 归约
    大规模并行计算
    借鉴思想:函数式编程

    filter

    过滤

    def _not_divisible(n):
        return lambda x: x % n > 0
    
    def primes():
        yield 2
        it = _odd_iter() # 初始序列
        while True:
            n = next(it) # 返回序列的第一个数
            yield n
            it = filter(_not_divisible(n), it) # 构造新序列
    

    判断列表字符是否大写,如果不是则去除,是则保留

    list_u = ["a", "B", "c", "F", "e"]
    re_d2 = filter(lambda s: s if s.isupper() else "", list_u)
    
    print(list(re_d2))
    

    命令式编程vs函数式编程

    命令式编程:
    func
    条件判断
    循环

    函数式编程: # 理论上可以用map\reduce 替换所有 if..else... for
    map
    reduce
    filter
    lambda 算子

    装饰器

    更多的是一种设计模式

    装饰器 二

    import time
    
    def time_dec(func):
        def func__(*args, **kw):
            print(time.time())
            return func(*args, **kw)
        return func__
    
    @time_dec
    def f1(name):
        print("This is a function" + name)
    
    f1("name)
    

    装饰器 三

    语法糖 @funcname
    采用了语法糖装饰函数,没带括号,已经运行了一层。
    需要注意调用和引用的区别,需要注意调用次数和引用次数。
    python装饰器大量应用了AOP的设计模式及思想:
    在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
    https://baike.baidu.com/item/AOP/1332219?fr=aladdin

    装饰器 四

    非常经典的关于多重装饰器的装饰顺序,应该深入理解。

    def decorator_a(func):
        print('Get in decorator_a')
    
        def inner_a(*args, **kwargs):
            print('Get in inner_a')
            return func(*args, **kwargs)
    
        return inner_a
    
    
    def decorator_b(func):
        print('Get in decorator_b')
    
        def inner_b(*args, **kwargs):
            print('Get in inner_b')
            return func(*args, **kwargs)
    
        return inner_b
    
    
    @decorator_b
    @decorator_a
    def f(x):
        print('Get in f')
        return x * 2
    # 初始化的时候,先初始化a,a才能返回一个函数对象用于初始化b,否则没有对象给b去初始化。
    # 初始化完成之后,返回的是一个b函数,调用b函数,才能返回a函数的调用从而完成整个装饰过程
    
    f(1)
    

    装饰器的传入参数,因为其通用性,需要传入可变参数:*args, **kwargs。。。

    装饰器 五

    加上关键字参数

    装饰器 六

    收尾
    装饰器思想:
    想对某一个被封装的单元修改某个功能,而不改变原代码。(开闭原则)
    对功能拓展

    哪些地方会用到:
    flask
    多重装饰

    相关文章

      网友评论

          本文标题:11.函数式编程:匿名函数、高阶函数、装饰器

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