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

    第一个python高阶函数:

     

    示例:计算一个值的阶乘(递归)

    #!/usr/bin/env python
    #coding=utf-8
    def fact(n):
           if n <= 1:
                   return n  #递归函数必须有退出条件
           return fact(n-1)*n   #调用函数自身  最终格式为return 2*3*4*5*6*7*8*9*10
    f = fact(10)   #python中函数递归最大深度为1000
    print f

    执行结果:

    [root@server24 ~]# ./func_9.py 
    3628800


    在python中尽量避免递归,绝大多数都是可以转为迭代,因为迭代要比递归快的多。

    同样利用迭代计算一个值的阶乘:

    def fact(n):
            ret = 1  #设置初值
            for i in range(n,1,-1):
                    ret *= i
            return ret
    print fact(10)
    执行结果
    [root@server24 ~]# ./func_9.py 
    3628800


    在python中函数是一等对象,可以像值一样赋值,作为函数的返回值返回。


    高阶函数

    以函数对象作为参数的函数叫高阶函数:

    下面为三个内置的高阶函数:


    filter() 过滤: filter(function or none ,seq)当函数返回值为true时,会将序列的当前值加进来

    >>> li = [1,2,3,4,5,6,7]
    >>> def f(x):
    ...     return x % 2 == 0
    ... 
    >>> filter(f,li)
    [2, 4, 6]

    用高阶函数手动实现内置filter函数

    #!/usr/bin/env python
    #coding=utf-8
    li = [1,2,3,4,5,6,7]
    def f(x):
            return x % 2 == 0   #return出去的是布尔值  true or false
    
    def afilter(f1,lis):
            lii = list()
            for i in lis:
                    if f1(i):
                            lii.append(i)
            return lii
    
    st = afilter(f,li)
    print st
    [root@server24 ~]# ./afilter.py 
    [2, 4, 6]


    map() 映射:对列表中每个元素执行一个函数

    >>> li = [2,3,4,5,6,7]
    >>> def f(x):
    ...     return x * 2
    ... 
    >>> map(f,li)
    [4, 6, 8, 10, 12, 14]

    用高阶函数手动实现高阶内置函数map()

    #!/usr/bin/env python
    #coding=utf-8
    li = [1,2,3,4,5,6,7]
    def f(x):
            return x * 2
    
    def amap(f1,lii):
            lis = list()
            for i in lii:
                    lis.append(f1(i))
            return lis
    
    st = amap(f,li)
    print st
    [root@server24 ~]# ./amap.py 
    [2, 4, 6, 8, 10, 12, 14]


    reduce() 化简将每次迭代结果与下一个元素一同执行一个二元的func函数

    >>> li = [2,3,4,5,6,7]
    >>> def sum(x,y):
    ...     return x * y
    ... 
    >>> reduce(sum,li)
    5040

    用高阶函数手动实现内置reduce

    #!/usr/bin/env python
    li = [0,1,2,3,4]
    def f(x,y):
            return x * y
    
    def reduc(f1,lis):
            st = lis[0]
            for i in range(1,len(lis)):
                    st = f1(st,lis[i])
            return st
    
    s = reduc(f,li)
    print s


    函数嵌套

    嵌套一般格式:

    def external():
            def internal():
                    expression
            return internal   #返回为嵌套,且与嵌套函数同级

    示例:无参数函数嵌套

    #!/usr/bin/env python
    #coding=utf-8
    def ext():
            print 'this is external'
            def internal():
                    print 'this is internal'
            return internal
    
    f =  ext() #调用函数ext,将返回函数internal赋值给变量f
    f()   #实际调用的是嵌套函数

    执行结果:

    [root@server24 ~]# ./ext.py 
    this is external
    this is internal

    计算一个函数的执行时间

    #!/usr/bin/env python
    #coding:utf-8
    
    import time  
    import datetime
    
    def func(arg):
            time.sleep(arg)
    
    def timezo(fun):
            def wrap(arg):
                    start = datetime.datetime.now()
                    fun(arg)
                    end = datetime.datetime.now()
                    cost = end - start
    #   **.total.seconds()用于计算秒数,是python2.7较之前版本新加的功能                
    		print "execute %s spend %s" % (fun.__name__,cost.total_seconds())
            return wrap
    f = timezo(func)  #返回函数wrap
    f(3) #再次调用函数wrap


    Decorator 装饰器:其实也是一个函数,是用来包装函数的函数。

    作用:解耦

    在使用装饰器后返回一个修改之后的函数对象,将其重新赋值原来的标识符,并永久丧失对原始函数的访问。将**.__name__,**.doc__等等改为装饰器内return的函数的属性

    如上计算函数执行时间的模块其实就是一个装饰器,一般用@来引用装饰函数

    示例:

    #!/usr/bin/env python
    #coding:utf-8
    import time
    import datetime
    
    def deco(func):
            '''第一个decorator是装饰函数,它的参数用来加强装饰的,其内部必须
    建一个接受被装饰函数的函数,然后返回这个对象'''
            def new_deco(arg):
                    '''装饰器里面一般原封不动地调用函数,不影响函数本身'''
                    start = datetime.datetime.now()
                    func(arg)
                    end = datetime.datetime.now()
                    cost = end - start
                    print 'exeute %s spend %s' % (func.__name__,cost)
            return new_deco  #必须返回
    
    @deco  #在调用func函数之前引用装饰器
    def func(arg):
            '''一切皆对象'''
            time.sleep(arg)
    
    func(2)
    '''返回来的是修改后的函数对象,即为装饰器内return的函数的属性'''
    print func.__name__
    print func.__doc__
    执行结果:
    [root@server24 ~]# ./deco.py 
    exeute func spend 0:00:02.002529
    new_deco
    装饰器里面一般原封不动地调用函数,不影响函数本身

    如果在使用装饰器时总是丢失函数本身的属性信息那将是很糟糕的事情,functools.wraps解决了这个问题,wraps在装饰器中可以将函数的函数名,文档字符串,参数信息等等复制过来

    示例:
    #!/usr/bin/env python
    #coding:utf-8
    import time
    import datetime
    import functools  #导入functools模块
    
    def deco(func):
            '''第一个decorator是装饰函数,它的参数用来加强装饰的,其内部必须
    建一个接受被装饰函数的函数,然后返回这个对象'''
            @functools.wraps(func) 
            def new_deco(arg):
                    '''装饰器里面一般原封不动地调用函数,不影响函数本身'''
                    start = datetime.datetime.now()
                    func(arg)
                    end = datetime.datetime.now()
                    cost = end - start
                    print 'exeute %s spend %s' % (func.__name__,cost)
            return new_deco  #必须返回
    
    @deco  #在调用func函数之前引用装饰器
    def func(arg):
            '''一切皆对象'''
            time.sleep(arg)
    
    func(2)
    '''返回来的是修改后的函数对象,即为装饰器内return的函数的属性'''
    print func.__name__
    print func.__doc__
    执行结果:
    [root@server24 ~]# ./deco.py 
    exeute func spend 0:00:02.002885
    func
    一切皆对象
  • 相关阅读:
    每日一题 为了工作 2020 0412 第四十一题
    每日一题 为了工作 2020 04011 第四十题
    每日一题 为了工作 2020 0410 第三十九题
    每日一题 为了工作 2020 0409 第三十八题
    每日一题 为了工作 2020 0408 第三十七题
    每日一题 为了工作 2020 0407 第三十六题
    每日一题 为了工作 2020 0406 第三十五题
    每日一题 为了工作 2020 0405 第三十四题
    学习总结(二十四)
    学习总结(二十三)
  • 原文地址:https://www.cnblogs.com/guoew/p/10391057.html
Copyright © 2011-2022 走看看