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__
    

      

  • 相关阅读:
    笔记7-7
    输出九九乘法表
    eclipse配置Maven——菜鸟篇
    IOC和AOP使用扩展之AOP详解实现类
    --------Hibernate框架之双向多对多关系映射
    易买网----------有感
    有关于TreeSet的自我理解
    爱学习当当网----图片的切换,书栏的循环滚动
    有关于购物车买买买?剁手吧
    致童年,一生都无法忘记的技能
  • 原文地址:https://www.cnblogs.com/liudefu/p/5021896.html
Copyright © 2011-2022 走看看