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__

  

转载于:https://www.cnblogs.com/liudefu/p/5021896.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值