面向对象是一种抽象,函数式也是一种抽象,它可以归于面向对象的范畴里,但其思想更接近实际的数学计算。
抽象程度很高,远离低级语言的甚至cpu的计算,纯粹的函数式编程语言写的函数没有变量,对于任何一个函数,只要输入确定,输出就是确定的,没有副作用。而有变量的程序语言编写的函数,由于变量可能不同,导致对于固定输入,不能保证固定的输出,称之为有副作用。
另一个特点,可以把函数当成参数传给另一个函数,函数也可以返回一个函数。
Python对函数式编程提供部分支持。因为python可以使用变量,所以不是纯粹的函数式编程语言。、
函数本身可以赋值给一个变量,函数名本身也是变量
高阶函数就是其有参数可以接受一个函数。
在高阶函数中,我们经常会用lambda表达式来表示低阶函数。
格式 lambda args: expression,其中 args 是一个以逗号隔开的参数列表,expression为该函数return的表达式运算结果(所以匿名函数的表达式数量有限,只有1个)
也可以把该函数赋值给一个变量
f = lambda x,y:x+y
f(1,2) # 3
刷选出序列中符合条件的元素
filter(function,序列) = Itrerator
其中function返回true 保留,返回false 丢弃
加深理解Iterator 可以表示一个序列
廖大大举出的经典应用,埃式筛法求素数。
第一个序列是,以2开始的所有自然数。拿出2并把所有可以被2整除的删除(也就是删除所有偶数),得到第一个素数2;
第二个序列是 就是上一步剩下的序列,拿出第一个元素(3),并把所有可以被3整除的删除,得到第二个素数3;
第三个序列是 就是上一步剩下的序列,拿出第一个元素(5),并把可以被该元素(5)整除的删除,得到第三个素数5;
归纳。。。就可以得到所有素数的序列。
sorted(list)
sorted(list,key=abs) #key函数
sorted(list,key=str.lower,reverse=True)
一个函数作为另一个函数的返回。
调用函数返回的变量(该变量也是一个函数)是一个闭包
做为返回的函数中,使用了上一层级函数的局部变量。这个变量会一直保存在这个返回中。这个变量可称为upValue。
注意upValue不要使用循环变量,不然会出现意外的结果,闭包中的upValue会随循环变化。
除了这种情况,闭包之间是没有影响的。
在返回函数中如果对上一级函数定义的变量重新赋值,则需要使用nolocal关键字声明一下该变量
函数对象有一个__name__属性,记录了函数的名字
在不修改函数定义下,为函数动态添加新功能,这种方式成为装饰器
decorator 是一个高阶函数,它返回一个函数,并且用@注释在想要装饰的函数上。
#假代码
decorator(f){ #装饰器
return func wrapper(*args, **kw){ #包裹函数 参数列表的扩展
extra #添加的功能
return f() #执行原函数的功能,并且可以保持原函数的返回
}
}
@decorator #原函数上边用 @decoratorName 注解
func f1 #原函数
@funcname 行为等价于 给var重新赋值了一个包含原函数功能的函数wapper的一个闭包。
decorated func var = funcname (decorated func var) ,原来的func var 还存在,作为一个upvalue存在在wapper里
如果@加入参数 @decorator(‘args1’) 就需要一个三层函数,第一层是返回decorator
@funcname (‘argument’)
行为等价于
decorated func var = funcname (‘argument’)(decorated func var)
经过装饰的函数对象 其__name__等属性会发生改变,所以装饰后要经常需要把原来的属性值还原,方法是,在wrapper 上 用@functools.wraps(func)注释
需要导入functools
import functools
OOP 的 decorator(设计模式中的装饰模式)需要通过继承和组合来实现。而Python的内置语法就可以实现当然也可以用OOP的方式实现。除此之外Pythonh的decorator出了用函数实现也能用类来实现。
把一个函数的某些参数固定住,让另外的参数发生变化
functools.partial
使用场合:当参数个数太多,需要简化时。