# -*- 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__