1.高阶函数
1.1 一等公民
函数在Python是一等公民(First-Class Object)
函数也是对象,是可调用对象
函数可以作为普通变量,也可以作为函数的参数、返回值
1.2 高阶函数
高阶函数(High-order Function)
数学概念 y = f(g(x))
在数学和计算机科学中,高阶函数应当是至少满足下面一个条件的函数
接受一个或多个函数作为参数
输出一个函数
练习:自定义sort函数
def sort(irerable,key = int,reverse = False):
newlist = []
for i in irerable:
ci = key(i) if key else i
for j,k in enumerate(newlist):
ck = key(k) if key else k
order = ci > ck if reverse else ci <ck
if order:
newlist.insert(j,i)
break
else:
newlist.append(i)
return newlist
sort([2,6,8,1,5])
1.3 内建高阶函数
1.3.1 排序sorted
定义 sorted(iterable, *, key=None, reverse=False) ->list
1.3.2 过滤filter
定义 filter(function, iterable)
对可迭代对象进行遍历,返回一个迭代器
function参数是一个参数的函数,且返回值应当是bool类型,或其返回值等效布尔值。
function参数如果是None,可迭代对象的每一个元素自身等效布尔值
list(filter(lambda x: x%3==0, [1,9,55,150,-3,78,28,123]))
list(filter(None, range(5)))
list(filter(None, range(-5, 5)))
1.3.3 映射map
定义 map(function, iterables) -> map object
对多个可迭代对象的元素,按照指定的函数进行映射
返回一个迭代器
list(map(lambda x: 2x+1, range(10)))
dict(map(lambda x: (x%5, x), range(500)))
dict(map(lambda x,y: (x,y), ‘abcde’, range(10)))
2. 柯里化**
指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数
z = f(x, y) 转换成 z = f(x)(y)的形式
def add(x):
def fun(y,z):
return x + y +z
return fun
fn = add(4)
fn(5,6)
def add(x,y):
def fun(z):
return x + y +z
return fun
add(4,5)(6)
def add(x):
def fun(y):
def ads(z):
return x + y +z
return ads
return fun
add(4)(5)(6)
3.装饰器
def add(x,y):
return x + y
def logger(fn):
def wrapper(*args,**kwargs):
print('begin')
x = fn(*args,**kwargs)
print('end')
return x
return wrapper
print(logger(add)(5,y=50))
换一种写法
add = logger(add)
print(add(x=5, y=10))
装饰器语法糖
def logger(fn):
def wrapper(*args,**kwargs):
print('begin')
x = fn(*args,**kwargs)
print('end')
return x
return wrapper
@logger # 等价于add = logger(add)
def add(x,y):
return x + y
print(add(45,40))
3.1 装饰器(无参)
它是一个函数
函数作为它的形参。无参装饰器实际上就是一个单形参函数
返回值也是一个函数
可以使用@functionname方式,简化调用
3.2装饰器和高阶函数
装饰器可以是高阶函数,但装饰器是对传入函数的功能的装饰(功能增强)
3.3带参装饰器
它是一个函数
函数作为它的形参
返回值是一个不带参的装饰器函数
使用@functionname(参数列表)方式调用
可以看做在装饰器外层又加了一层函数,这个函数可以多参数
import datetime, functools
import datetime, functools
def logger(fn):
@functools.wraps(fn)
def wrapper(*args, **kwargs):
start = datetime.datetime.now()
ret = fn(*args, **kwargs)
delta = (datetime.datetime.now() - start).total_seconds()
if delta > 3: print('too slow')
return ret
return wrapper
@logger
def add(x, y): pass
@logger
def sub(x, y): pass
print(add.__name__, sub.__name__)
logger什么时候执行?
只要定义就被执行
logger执行过几次?
两次
wraps装饰器执行过几次?
两次
wrapper的__name__等属性被覆盖过几次?
零次,各是各的
add.name 打印什么名称?
add
sub.name 打印什么名称?
sub