• Python3(十) 函数式编程: 匿名函数、高阶函数、装饰器


    一.匿名函数

    1.定义:定义函数的时候不需要定义函数名

    2.具体例子:

    #普通函数

    def add(x,y):
     
        return x + y

    #匿名函数

    lambda x,y: x + y

    调用匿名函数:

    f = lambda x,y: x + y    #赋值后可以调用
     
    print(f(1,2)

    lambda中(也就是:后面)只能进行简单的表达式操作,不能进行赋值操作。

    二. 三元表达式

    格式为:条件为真时返回的结果 if 条件判断 else 条件为假时返回的结果

    x = 2
     
    y = 1
     
    r = x if x > y else y
     
    print(r)
     
    #2

    三元表达式在lambda中运用比较多。

    三.map类

    1.定义:map(函数,序列),把序列中所有值依次传到函数中并依次接受返回结果组成一个list。

                  其实是一个函数的映射。

    2.求平方:

    list_x = [1,2,3,4,5,6,7,8]
     
     
    def square(x):
     
        return x * x
     
     
    r = map(square,list_x)
     
    print(list(r))
     
    #[1, 4, 9, 16, 25, 36, 49, 64]

    四.map与lambda

    将map和lambda函数结合:

     1

    list_x = [1,2,3,4,5,6,7,8]
     
    r = map(lambda x: x * x,list_x)
     
    print(list(r)

    2 接受多个参数:

    list_x = [1,2,3,4,5,6,7,8]
     
    list_y = [1,2,3,4,5,6,7,8]
     
    r = map(lambda x,y: x * x + y,list_x,list_y)
     
    print(list(r))

    注意:若个数不相等,不会报错,但只能计算到最少的那位

    五.reduce

    1.

     2. reduce运算的规则:做连续的计算,连续的调用lambda表达式。

       reduce下的函数一定要有两个参数。

    3.例子:

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

    运算过程:初始取前两位,之后将计算结果作为x传进去继续顺序取:

    ((((((1 + 2)+3) + 4)+ 5)+6)+7)+8

    4.注意点:

    • 继续做什么操作是lambda确定的,不仅只能够相加。
    • 最后一位可以设定初始值,在第一次计算中就进行计算了:

             eg:r = reduce(lambda x,y:x + y,list_x,10)

    六. filter

    1.filter可以过滤掉不符合规则的数据。

     

    2.例子:

     剔除数据为0的元素:

    list_x = [1,0,0,1,0,1,1,0,1]
     
    r = filter(lambda x: True if x == 1 else False,list_x)
     
    print(list(r))
     
    #[1, 1, 1, 1, 1]

    简化为:

    list_x = [1,0,0,1,0,1,1,0,1]
     
    r = filter(lambda x: x ,list_x)
     
    print(list(r))
     
    #[1, 1, 1, 1, 1]

    filter返回值的要是真和假才能完成过滤

    七.命令式编程vs函数式编程

      命令式编程涉及到 def  if else for

      函数式编程涉及到 map reduce filter lambda(算子)

    八. 装饰器 一

    import time
     
    def f1():
     
        print(time.time())
     
        print('This is a function')
     
     
     
    f1()
     
    #1532404967.3804688    #Unix时间戳
     
     This is a function

    如果很多的函数都要获取时间的功能:

    import time
     
    def f1():
     
        print('This is a function')
     
     
    def f2():
     
        print('This is a function')
     
     
    def print_current_time(func):
     
        print(time.time())
     
        func()
    
     
    print_current_time(f1)
     
    print_current_time(f2)

    这种需求变更方案的缺点:打印时间的需求是属于每个函数本身的,并不是新增加的,并没有体现函数本身的特性。

    这就是装饰器所要解决的问题。

    装饰器 二

    编写装饰器:

    import time
     
    def decorator(func):
     
        def wrapper():
     
            print(time.time())
     
            func()
     
        return wrapper
    
     
    def f1():
     
        print('This is a function')
     
    f = decorator(f1)    #f得到了return的wrapper
     
    f()

    装饰器 三

    语法塘:

    import time
     
     
    def decorator(func):
            def wrapper():
     
            print(time.time())
     
            func()
     
        return wrapper
     
     
     
    @decorator    #@符号
     
    def f1():
     
        print('This is a function')
     
    f1()

    没有改变调用的逻辑也没有改变函数编码。是装饰器的意义所在。

    @decorator相当于对f1()装饰。

    装饰器 四

    1.带参函数的装饰器:

    import time
     
    def decorator(func):
     
        def wrapper(func_name):
     
            print(time.time())
     
            func(func_name)
     
        return wrapper
     
     
    @decorator
     
    def f1(func_name):
     
        print('This is a function named' + func_name)
     
    
    f1('test_func')

    2.若多个函数接受不同数量的参数:

    import time
     
    def decorator(func):
     
        def wrapper(*args):
     
            print(time.time())
     
            func(*args)
     
        return wrapper
     
    @decorator
     
    def f1(func_name):
     
        print('This is a function named' + func_name)
     
    @decorator
     
    def f2(func_name1,func_name2):
     
        print('This is a function named'+func_name1 )
        print('This is a function named'+ func_name2)
     
     
     
    f1('test_func')
     
    f2('test_func1','test_func2')    #可以支持不同参数个数的函数

    装饰器 五

    1.*args不支持**关键字参数

    支持关键字参数:

    import time
     
     
     
    def decorator(func):
     
        def wrapper(*args,**kw):    #加入**kw,较为完整
     
            print(time.time())
     
            func(*args,**kw)
     
        return wrapper
     
     
     
    @decorator
     
    def f1(func_name):
     
        print('This is a function named' + func_name)
     
     
     
    @decorator
     
    def f2(func_name1,func_name2):
     
        print(func_name1 + func_name2)
     
     
     
    @decorator
     
    def f3(func_name1,func_name2,**kw):
     
        print(func_name1 + func_name2)
     
        print(kw)
     
     
     
    f1('test_func')
     
    f2('123','234')
     
    f3('123','234',a = 1, b = 2,c = '123')
     
     
     
    #1532408656.565761
     
    #This is a function namedtest_func
     
    #1532408656.5667255
     
    #123234
     
    #1532408656.5677273
     
    #123234
     
    #{'a': 1, 'b': 2, 'c': '123'}

    2.

    def decorator(func):
    
        def wrapper(*args,**kw):    #加入**kw,较为完整
    
            print(time.time())
    
            func(*args,**kw)
    
        return wrapper
    
    func(*args,**kw)这个形式,无论什么方式都可以调用。

    装饰器 六

    如果想对某个封装单元修改,可以加上装饰器。

    不需要破坏代码实现,易于代码复用。

    一个函数能够有多个装饰器。

    需要验证身份的函数上加上专门的装饰器之类的用途。

    
    
    
  • 相关阅读:
    学习:大文件统计与排序
    共享库SidebySide之Windows Shared Assembly
    Bundle是个好东西
    所谓的代码段、数据段
    [design decision] common case vs. rare case
    如何给C++设计一个GC
    玩一把tesseract
    [design decision]让工具依赖于naming convention是个拙劣的做法
    监控域名可用性并自动发信
    调试lua代码
  • 原文地址:https://www.cnblogs.com/wlgaojin/p/12296454.html
Copyright © 2020-2023  润新知