前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python的函数式编程

Python的函数式编程

作者头像
ZONGLYN
发布2019-08-08 11:49:33
4580
发布2019-08-08 11:49:33
举报
匿名函数
特点:
    定义函数时不需要定义函数名
实现:
    借助 lambda 关键字
    lambda parameter_list: expression
    注意:expression只能包含表达式!不能包含语句!

示例:
    一般函数:
        def add(x, y):
        return x + y
    上述add函数的匿名形式:(匿名函数 或 叫做Lambda表达式)
        lambda x,y: x+y


匿名函数的调用:
    因为没有名字,所以需要赋值给变量,然后调用
    f = lambda x,y: x+y
    print(f(1,2)) #输出 3
三元表达式
地位:
    表达式版本的if else 语句
实现:
    Java的形式  x > y ? 1 : 1
    Python的三元表达式
    [条件为真时返回的结果] if [条件判断] else [条件为假时的返回结果]
示例:
    x = 1
    y = 2
    print( True if x > y else False) #输出 False
class map(func,*iterables)
使用场景
    对序列中的全部元素执行相同的操作
应用:
    求列表中每个数字的平方
示例:
    list_x = [1,2,3,4,5,6]

    def func(x):
        return x * x
    print(map(func, list_x))    
    #输出 <map object at 0x0000000000A5D7F0>

    print(list(map(func, list_x)))  
    #输出 [1, 4, 9, 16, 25, 36]
注意:
    map会吧集合中的每个元素都传入到第一个参数,func中去
    即按照一定的规则,对一族元素进行映射,规则就是func中的逻辑

map+lambda:
注意:
    map(func,*iterables)结合Lambda表达式
    直接替换掉参数func
    注意第二个参数 *iterables,带星号,表示可变参数
    如果func参数有多个,第二个参数位置可以传入多个list
示例:
    完成返回平方的功能:
    print( list( map( lambda x: x*x, [1,2,3,4,5] ) ) )
    #输出 [1, 4, 9, 16, 25]

    Lambda表达式有两个参数
    print( list( map( lambda x,y: x*y, [1,2,3,4,5],[1,2,3,4,5] ) ) )
    #输出[1, 4, 9, 16, 25]

    注意多个参数时会一一对照,多余会丢弃
    print( list( map( lambda x,y: x*y, [1,2,3,4,5],[1] ) ) )
    #输出[1]
    上述输出只有一个元素,因为输入的两个参数只有第一个元素满足运行条件
def reduce
注意:
    map类在全局命名空间,不需要引入模块,reduce函数需要引入functools
    def reduce(function,sequence,initial=None)
示例:
    from functools import reduce
    list_x = [1,2,3,4]    
    #完成求和
    print( reduce( lambda x,y:x+y, list_x ) )
    #输出 10 运算过程:
    #1   2   3   4 ...
    #    3   3   4 ...
    #        6   4 ...
    #            10...

应用场景:
    连续规约计算,从前向后对数据进行两两规约计算

带initial参数:
    print( reduce( lambda x,y:x+y, list_x, 10 ) )
    #输出 10 运算过程:
    #10  1   2   3   4 ...
    #    11  2   3   4 ...
    #        13  3   4 ...
    #            16  4 ...
    #                20

扩展:
    map/reduce 映射+规约,进行并行计算(大数据处理)
class filter(func or None, iterables)
注意:
    由参数可知,只能对一个序列进行处理,参数func仍然可以被Lambda表达式替换
    另:第一个参数必须可以返回True/False 或者代表True/False的值
    filter依靠TF来判断是否要剔除,返回false表示保留
示例:
    print( filter( lambda x:False if x == 0 else True, [0,0,1,2,3,0] ))
    #输出 <filter object at 0x000000000111D828>

    print( list( filter( lambda x:False if x == 0 else True, [0,0,1,2,3,0] )))
    #输出 [1, 2, 3]

对比:
    命令式编程:依靠def,if else,for/while等等

    函数式编程:依靠map,reduce,filter + Lambda(三大函数 + 算子)
    解释:
        map,reduce近似循环
        filter近似判断
        Lambda近似函数
    上述集合使用,可以完成流程控制
注意:
    Python只是支持部分函数式编程的特性,本身并不是函数式编程语言
装饰器
地位:
    非常有用、常用,是一种设计模式,类似Java的注解
示例:
    对所有函数追加打印当前时间的功能
代码:
    import time
    def func1():
        print(time.time())
        #输出 1509550613.9346058 Unix时间戳
        print('This is a function')
    func1()
追加修改原则:
    开闭原则:对修改是封闭的,对扩展是开放的,如果需要打印时间,会迫使修改函数内部


进一步:
    使用函数式编程思想的封装,没有违反开闭原则
    def func2():
        print('This is a function')         
    def print_time(func):
        print(time.time())  
        func()
    print_time(func2)
    上述缺点:打印时间并没有和原函数绑定

再进一步:
    使用装饰器完成上述功能
    装饰器的基本结构:
        def decorator():
            def wrapper():
                pass#装饰器的逻辑
            return wrapper
    示例:
        import time
        def func1():
            print('This is a function')
        #构造装饰器
        def decorator(func):
            def wrapper():
                print(time.time())
                func()
            return wrapper

        decorator(func1)() 完成调用
    解释:
        真正业务逻辑在wrapper内
    缺点:
        仍然没有将打印时间和原始函数绑定起来

再进一步:
    使用装饰器语法糖,使用@符号
    代码:
        import time

        #构造装饰器
        def decorator(func):
            def wrapper():
                print(time.time())
                func()
            return wrapper
        @decorator
        def func1():
            print('This is a function')
        func1() #完成调用,而且没有改变原有调用逻辑
评价:
    这才是完整的有意义的装饰器的使用方法,只需要在原有函数定义上添加
    @decorator就会执行附加操作,体现了AOP面向切面编程
对带参数的原函数添加装饰器
示例:
    import time

    #构造装饰器
    def decorator(funcname):
        def wrapper(*fc): 
        #此处的参数,应该和被修饰函数的参数个数相对于,
        #但是为了通用性,应该使用*params可变参数形式
            print(time.time())
            funcname(*fc)
        return wrapper

    @decorator 
    def func1(f_param):
        print('This is ',f_param)

    @decorator 
    def func2(param1,param2):
        print('This is ',param1,param2)

    func1('Tom')
    func2('Tom','Jack')
    上述成功完成了对不同参数的函数进行添加装饰器

进一步优化
适应关键字参数:
    import time

    #构造装饰器
    def decorator(funcname):
        def wrapper(*fc,**kw): #参数**kw适用于关键字参数
            print(time.time())
            funcname(*fc,**kw)
        return wrapper

    @decorator
    def func2(param1,**param2):
        print('This is ',param1,param2)
    func2('Tom',a = '1',b = '2') #正确适应了关键字参数的函数

关键字参数,回顾:

    对于含有关键字参数的函数 
        def func2(param1,**param2):
            print('This is ',param1,param2)
        func2('Tom',a = '1',b = '2')
        输出 This is  Tom {'b': '2', 'a': '1'}

综上:
    此时的装饰器:
    def decorator(funcname):
        def wrapper(*fc,**kw):  
            print(time.time())
            funcname(*fc,**kw)
        return wrapper
    在待装饰函数具有多个可变参数,或者包含关键字参数的情况均可使用


装饰器小结:
    装饰器的思想:对封装的单元追加行为,保证原有单元的稳定性,
    不破坏单元内的代码,遵循开闭原则,更加体现了装饰器内代码的复用

应用场景:
    flask内,添加@api.route可以使函数变为控制器
        @api.route('/get',methods=['GET'])
        def test_http():
            p = request.agrs.get('name')
            return p,200

    添加多个装饰器,追加不同的操作
        @api.route('/get',methods=['GET'])
        @auth.login_required
        def get_money():
            p = request.agrs.get('psw')
            r = generate_hash(p)
            return 'user',200
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-10-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 匿名函数
  • 三元表达式
  • class map(func,*iterables)
  • def reduce
  • class filter(func or None, iterables)
  • 装饰器
  • 对带参数的原函数添加装饰器
相关产品与服务
GPU 云服务器
GPU 云服务器(Cloud GPU Service,GPU)是提供 GPU 算力的弹性计算服务,具有超强的并行计算能力,作为 IaaS 层的尖兵利器,服务于深度学习训练、科学计算、图形图像处理、视频编解码等场景。腾讯云随时提供触手可得的算力,有效缓解您的计算压力,提升业务效率与竞争力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档