zoukankan      html  css  js  c++  java
  • python 函数式编程 高阶函数 装饰器

    # -*- coding:gb2312 -*-
    #coding=utf-8
    # 高阶函数
    import math
    def is_sqr(x):
        y = int(math.sqrt(x))
        return x == y*y
    print filter(is_sqr, range(1, 101))
    
    # 返回函数
    # 作用:延迟执行
    def calc_prod(lst):
        def lazy_prod():
            def f(x,y):
                return x*y
            return reduce(f, lst)
            
    	return lazy_prod
    
    f = calc_prod([1, 2, 3, 4])
    print f()
    
    
    # 匿名函数
    print filter(lambda s: s and len(s.strip()) > 0, ['test', None, '', 'str', '  ', 'END'])
    
    # 装饰器 @decorator
    print "....装饰器...."
    def log(f):
        # 写法一
        # def fn(x):
            # print 'call ' + f.__name__ + '()...'
            # return f(x)
        # return fn
        # 写法二
        print 'call ' + f.__name__ + '()...'
        return f
    
    @log
    def factorial(n):
        return reduce(lambda x,y: x*y, range(1, n+1))
    print factorial(10)
    
    # 无参数装饰器
    print "....无参数装饰器...."
    
    import time
    # 写法一,接收一个函数返回一个新函数,但是返回的新函数必须符合原函数的调用规则,即参数应该一致。
    # 如,log()是无参函数,则调用就不能传递参数
    def performance(f):
        def log(x):
            print time.time()
            return f(x)
        return log
    
    # 写法二,不用函数封装,直接添加新的操作
    def performance2(f):
        print time.time()
        return f
    
    # 写法一优化,被装饰的函数前后可以执行不同的操作,即,返回的新函数可以在任意时候调用被装饰的函数
    def performance3(f):
        def log(x):
            start_time = time.time()
            r = f(x)  # 在新函数的此处调用被装饰函数,但是,此时被装饰函数尚未被调用,因为log函数尚未被调用,只是返回了函数对象
            time.sleep(1)
            end_time = time.time()
            print 'call %s() in %fs' % (f.__name__, (end_time - start_time))
            return r
        return log
    
    # 写法二优化,不用函数封装,直接添加新的操作
    def performance4(f):
        start_time = time.time()
        r = f # 在此处调用被装饰函数
        time.sleep(1)
        end_time = time.time()
        print 'call %s() in %fs' % (f.__name__, (end_time - start_time))
        return r
    
    @performance4
    def factorial(n):
        return reduce(lambda x,y: x*y, range(1, n+1))
    
    print factorial(10)
    
    
    
    # 带参数装饰器
    print "....带参数装饰器...."
    
    def performance_parm(unit='s'):
        def performance5(f):
            def log(x):
                start_time = time.time()
                r = f(x)  # 在新函数的此处调用被装饰函数,但是,此时被装饰函数尚未被调用,因为log函数尚未被调用,只是返回了函数对象
                time.sleep(1)
                end_time = time.time()
                print 'call %s() in %fs %s' % (f.__name__, (end_time - start_time), unit)
                return r
            return log
        return performance5
        
    
    @performance_parm('M')
    def factorial(n):
        return reduce(lambda x,y: x*y, range(1, n+1))
    
    print factorial(10)
    
    
    # 完善decorator
    print "....完善decorator...."
    print factorial.__name__
    # => log
    # 可见,由于decorator返回的新函数函数名已经不是'f2',而是@log内部定义的'wrapper'。这对于那些依赖函数名的代码就会失效。
    # decorator还改变了函数的__doc__等其它属性。
    # 如果要让调用者看不出一个函数经过了@decorator的“改造”,就需要把原函数的一些属性复制到新函数中。
    # Python内置的functools可以用来自动化完成这个“复制”的任务
    import functools
    def performance5(f):
        @functools.wraps(f)
        def log(x):
            start_time = time.time()
            r = f(x)  # 在新函数的此处调用被装饰函数,但是,此时被装饰函数尚未被调用,因为log函数尚未被调用,只是返回了函数对象
            time.sleep(1)
            end_time = time.time()
            print 'call %s() in %fs %s' % (f.__name__, (end_time - start_time), unit)
            return r
        return log
    
    @performance5
    def factorial(n):
        return reduce(lambda x,y: x*y, range(1, n+1))
    print "....装饰器修改后...." 
    print factorial.__name__
    

      

  • 相关阅读:
    51nod 1179 最大的最大公约数 (数论)
    POJ 3685 二分套二分
    POJ 3045 贪心
    LIC
    HDU 1029 Ignatius and the Princess IV
    HDU 1024 Max Sum Plus Plus
    HDU 2389 Rain on your Parade
    HDU 2819 Swap
    HDU 1281 棋盘游戏
    HDU 1083 Courses
  • 原文地址:https://www.cnblogs.com/liudefu/p/5021896.html
Copyright © 2011-2022 走看看