一、高阶函数
函数的参数为函数或者函数的返回值为函数的称为高阶函数
当我们使用一个函数作为参数时,实际上将指定的代码传递给了目标函数
定义一个函数,返回一个列表中所有的偶数
l = [1,2,3,4,5,6,7,8,9,10]
new_ lst = []
def fn1(lst):
for i in l:
if i % 2 == 0:
new_lst.append(i)
return lst
result = fn1(l)
print(result)
定义一个函数,返回一个中所有的奇数
l = [1,2,3,4,5,6,7,8,9,10]
new_ lst = []
def fn1(lst):
def fn2(i)
if i % 2 == 0:
return True
for i in lst:
if fn2():
new_lst.append(i)
return new_lst
result = fn1(l)
print(result)
我们希望定义一个函数,根据客户的不同需求返回满足要求的不同列表
#判断一个值是否是偶数
def fn1(i):
if i % 2 == 0:
return True
#判断一个值是否大于5
def fn2(i):
if i > 5:
return True
def fn3(func,lst): #函数的参数仍是 函数func
for i in lst:
if func(i):
new_lst.append(i)
return new_lst
l = [1,2,3,4,5,6,7,8,9]
result = fn3(fn1,l) #fn1满足客户需求的函数,l为被筛选的列表
print(result)
向fn3中传入不同满足条件的函数(当fn3的参数为fn1时,返回全是偶数的列表;当fn3的参数为fn2时,返回大于5的列表),就会返回满足条件的列表
fn3函数的参数仍是函数,因此fn3是一个高阶函数 :
二、匿名函数
1.filter()函数
filter()可以从序列中过滤出满足条件的列表,并保存到新的列表中
参数1:函数,根据该函数来过滤序列(可迭代结构)
参数2:需要过滤的序列(可迭代结构)
返回值:过滤后的新的序列
print(filter(fn1,l)) #输出结果为:<filter object at 0x01565BF0>
#要想查看列表中的值,需要在filter前加list
print(list(filter(fn1,l)))
2.匿名函数
匿名函数就是一个lambda表达式,可以用来创建一个简单的函数,是函数创建的另一种方式
语法:
lambda 参数列表:返回值
匿名函数最大的好处:只会调用一次,用完就会从内存中消失
如果实现函数的功能叫简单,且只调用一次建议使用匿名函数
定义一个函数,返回任意两个数的和
def fn(a,b):
return a+b
#转换为匿名函数如下:
lambda a,b:a+b
#匿名函数的调用
print( (lambda a,b:a+b)(1,2)) #不常用
#或者
r = lambda a,b:a+b
print(r(1,2)) #不常用
3.filter()与匿名函数结合
#使用filter()与匿名函数返回倍数为3的列表
print(list(filter(lambda i:i % 3 == 0,l)))
4.map()函数
map()函数对可迭代对象中所有元素做指定的操作,然后将其添加到一个新的对象中
#对列表中所有元素+1
r = list( map(lambda i:i+1,l) )
print(r)
匿名函数一般都是作为参数使用,其他地方不用
5.sort()函数
sort()对列表进行排序
l = ['cccc','aaa','bb','dddddd']
l.sort(key = len) #按字符串长度排序 key = len 关键字传参,参数为len函数
l1 = [1,'2',3,'4','5']
l1.sort(key = int) #将字符串转化为 整型进行排序 参数为int函数
6.sorted()函数
sorted()对列表进行排序,不改变原来的列表,会返回一个新的列表
lst = [5,'2',3,'4',1]
print("排序前",lst)
lst.sorted()
print("排序后",lst) #lst没有发生任何变化 [5,'2',3,'4',1],使用sort则lst为排序后的顺序
print(lst.sorted()) #输出排序后的列表 [1,'2',3,'4',5]
三、闭包
闭包可以创建一个
#定义一个函数,求任意数的平均值
num = []
def fn(n):
num.append(n)
return sum(num)/len(num)
print(fn(10))
num定义在全局变量中,任何人都可以修改该列表,不利于数据的稳定,可以将num修改为函数变量,保证只有该函数中可以访问该变量
def new_avg():
#创建一个变量用来保存数据
num = []
def avg(n):
num.append(n)
return sum(num)/len(num)
return avg
r = new_avg()
result = r(10)
print(result)
形成闭包的条件
函数嵌套且将内部函数作为返回值返回
内部函数必须使用到外部函数的变量(num)
四、装饰器的引入
我们希望可以在程序开始时输出“程序开始执行”,在程序结束时输出“程序执行结束”
def add(a,b):
print("程序开始执行")
r = a+b
print("程序执行结束")
return r
当有多个函数需要完成以上功能时,我们可以对每个函数都增加以上两个输出语句,但这会导致以下问题:
1.当有大量函数需要实现该功能时,需进行的操作太庞大
2. 不利于程序的后期维护
3. 违反了程序的开闭原则(ocp),要求对程序扩展但关闭对程序的修改
不修改原函数,对函数进行扩展
def fn():
print("我是fn函数")
#创建一个函数,对原函数进行扩展
def fn2():
print("程序开始执行..")
fn()
print("程序执行完毕...")
fn2()
'''
输出结果:
程序开始执行...
我是fn函数
程序执行完毕...
'''
装饰add()函数
def add():
return a+b
def fn2(a,b):
print("程序开始执行")
r = add(a,b)
print("程序执行完毕")
return r
result = fn2(1,2)
print(result)
五、装饰器的使用
对不同函数进行装饰时,需要定义不同的函数实现该功能,较为繁琐。我们可以定义一个高阶函数来完成该功能
def start_end(old):
#old 为需要装饰的参数
def new_func(*args,**kwargs): #*args接收不定长位置参数,**kwargs接收不定长关键值参数,函数的装包
print("程序开始执行")
result = old(*args,**kwargs) #函数的解包
print("程序执行结束")
return result
return new_func
r = start_end(add)
res = r(1,2)
print(res)
start_end() 类似于这样的函数都是装饰器
通过装饰器可以在不修改函数的基础上对函数进行扩展
在开发过程中都是通过装饰器来扩展函数的功能的
@start_end
def fn1():
print("byebye....")
fn1()
'''
输出结果:
程序开始执行
byebye....
程序执行结束
'''
实现对fn1的装饰