--------------以下部分摘自马哥教育
函数的一般形式:
y= f(x)
x成为自变量,y是x的函数 (域值)
高阶函数:
y=f(g(x))
定义:
接受一个或者多个函数作为参数
返回一个函数
def counter(base): def inc(step=1): nonlocal base base += step return base return inc foo = counter(5) print(foo()) f1 = counter(5) f2 = counter(5) print(id(f1), id(f2), id(foo))
因为上面例子中,返回的是一个函数,即可以看成返回的是一个对象,所以在调用时,尽管参数值一样,但是,不同的调用产生了不同的对象,存放的地址是不一样的。
高阶函数的用途:
函数作为返回值,往往会形成闭包;
函数作为参数,应用很广泛。
排序问题举例:
lst = [2, 4, 6, 8, 4, 6, 3, 2, 4, 5] def sort(lis, fn=lambda a, b: a < b): def compare(a, b): return a < b if asc else a > b newlst = [] for x in lst: for i, y in enumerate(newlst): if fn(x, y): newlst.insert(i, x) break else: newlst.append(x) return newlst print(sort(lst)) print(sort(lst, lambda x, y: x < y)) print(sorted(lst, reverse=True)) # sorted 排序函数 print(list(map(lambda x: (x, x + 1), lst))) # map 映射函数 print(list(filter(lambda x: x > 3, lst))) # filter 过滤函数
上面例子中我们把逻辑抽象成一个函数,然后有外部作为参数传入,大大增加编程的灵活性。
柯里化
定义:指的是将原来接受两个参数函数的函数变成新的接受一个参数的函数的过程,新的函数返回一个以原有第二个参数为参数的函数
数学表示:z=f(x,y)转换成z=f(x)(y)
举例:
def add(x, y): return x + y print(add(4, 5)) # z=f(x,y) def new_add(x): def inner(y): return x + y return inner print(new_add(4)(5)) # z=f(x)(y)
装饰器
装饰器是一个高阶函数-------函数作为返回值,函数作为参数。
定义:装饰器就是一个函数,它接受一个业务函数作为参数,返回一个包装函数,而包装函数里面包装了(闭包了)原有的业务函数。
作用:对原有的业务函数在外围进行业务增强,而不用写过多的侵入式代码侵入到原有业务函数的核心业务,结果就是增强了原有业务函数的纯净性和可读行。
举例:
import datetime import time def logger(fn): # fn = add,add传入的是fn def wrapper(*args, **kwargs): # 定义可变参数和可变关键字参数;在这个例子中,变量add指向了装饰器函数,从而使wrapper函数有了参数 # before print('args = {} , kwargs = {}'.format(args, kwargs)) # 功能增强 start = datetime.datetime.now() ret = fn(*args, **kwargs) # 解构可变参数和关键字参数,还原了业务函数add # after print(ret) delat = (datetime.datetime.now() - start).total_seconds() if delat > 2: print("{} took {}S".format(fn.__name__, delat)) else: print("so fast") return ret # 返回的add函数的原型,保证add函数原有内容,防止返回NONE值。 return wrapper # 返回的warpper是增强版本的add函数 @logger # 相当于 add = logger(add)而等号左边的add相当于指向了函数warpper ,而@是语法糖 def add(x, y): time.sleep(3) return x + y # add = logger(add) # return warp ,warp = 增强版的fn print(add(4, y=6))
装饰器相当于一个语法糖,让原业务代码看起来更加有业务性,美化了写法,让别人更容易懂。