版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
高阶函数
满足2个条件任意一个都是高阶函数
- 接受函数作为参数
- 将函数作为返回值的函数也是高阶函数
当我们使用一个函数作为参数时,实际上就是将指定的代码传给目标函数
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
new_l = []
def fn1(i): # 定义一个函数用来检测序列中的数是否是偶数
if i % 2 == 0:
return True
return False
def fn2(i): # 检测序列是否大于5
if i > 5:
return True
return False
def fn3(i): # 检测3的倍数
if i % 3 == 0:
return True
return False
def fn(func, lis):
for n in lis:
if func(n):
new_l.append(n)
return new_l
r1 = fn(fn1, l)
print(r1)
# [2, 4, 6, 8, 10]
# r2 = fn(fn2, l)
# print(r2)
# [6, 7, 8, 9, 10]
# r3 = fn(fn3, l)
# print(r3)
# [3, 6, 9]
匿名函数
lambda表达式,用来创建一些简单的函数,它是函数创建的另一种方式,其实现了python中的最小函数
语法:lambda 参数列表 :返回值
- 匿名函数最大的好处是只会调用一次,用完之后会从内存中消失
- 匿名函数一般都是作为参数使用,其他地方不用
你会发现直接使用lambda返回的是内存地址,且该内存地址没有函数名,但fn函数有(函数名就是fn),所以lambda称为匿名函数
def fn(x):
return x*x
r = fn(3)
print(r)
print(fn)
# 相当于
print(lambda x:x*x)
print((lambda x:x*x)(3))
# <function fn at 0x000001F100215048>
# 9
# <function <lambda> at 0x00000208573755E8>
# 9
fn = lambda a, b:a+b
print(fn(1,1))
# 2
匿名函数一般作为参数使用,但上述方法是直接使用,我们引入
filter(funcation, sequence)
- 可以从序列中过滤出符合条件的元素,保存到另一个序列中
- 参数:
- 函数(function),根据该函数来过滤序列(可迭代结构),可有可无
- 序列(sequence),需要过滤的序列(可迭代结构)
- 返回值:
- 过滤后的新序列
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
new_l = []
def fn1(i): # 定义一个函数用来检测序列中的数是否是偶数
if i % 2 == 0:
return True
return False
r = filter(fn1,l)
print(r) # 其返回的扔是filter对象
print(list(r)) # 加list即可返回新序列
# <filter object at 0x00000140872FD6C8>
# [2, 4, 6, 8, 10]
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
r = filter(None,l)
print(r)
print(list(r))
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
r = filter(lambda x:x*x,range(10))
print(r)
print(list(r))
# <filter object at 0x0000023C57D474C8>
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
map()
- map()函数可以对可迭代对象中所有元素做指定的操作,然后将其添加到一个新的对象中返回
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
r = map(lambda i:i+1,l)
print(r)
print(tuple(r)) # 也可用元组返回新的序列
# (2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
sort()
- sort()函数可以对列表当中的元素进行排序
sort之前有讲过,这里介绍另一种方法,在参数值加入函数
lis = [1, 5, 4, 2, 6, '8', '6']
r = lis.sort(key = int)
print(r)
print(lis)
# None
# [1, 2, 4, 5, 6, '6', '8']
sorted()
- 会返回一个新的列表
lis = [1, 5, 4, 2, 6, '8', '6']
r = sorted(lis, key = int)
print(r)
# [1, 2, 4, 5, 6, '6', '8']
闭包
- 通过闭包可以创建一些只有当前函数才能访问的对象,还可以将一些私有的对象藏到闭包中
- 当我们不希望别人修改我们的数据时,将数据放入函数内部,不要放到全局变量中
- 形成闭包的条件
- 函数嵌套
- 将内部函数作为返回值返回
- 内部函数必须使用到外部函数的变量
r = []
def avg():
r = []
def count(n):
r.append(n)
return sum(r)/len(r)
return count # 这里返回的是count函数对象
a = avg() # 我们用a接受avg函数,实际上接受的是avg的返回值,其返回的是count对象
print(a(10)) # a(10)实际上是count(10)
print(r) # 我们打印r可以看到,我们在内部函数修改了列表r,全局变量中的r没有改变
# 10.0
# []
装饰器的引入
当我想修改一个函数时,我们直接修改函数体即可,但当我们向修改多个函数,就会产生一些问题
- 修改数量很多
- 不方便后期的维护
- 会违反开闭原则(ocp),程序设计,要求对程序的扩展,但要关闭对程序的修改
不修改原函数对函数进行修改
def add(a, b):
return a+b
def expand(a, b):
print('函数执行前')
r = add(a, b)
print('函数执行后')
return r
r = expand(1, 1)
print(r)
# 函数执行前
# 函数执行后
# 2
如果我想要在更改其他函数,该expand就不好用了,也要修改,那我还不如一个一个函数改,下面我们使用装饰器
装饰器的使用
def add(a, b):
return a+b
def decorator(old):
def new_func(*args, **kwargs):
print('我来自装饰器')
r = old(*args, **kwargs)
return r
return new_func
r = decorator(add)
print(r(1, 1))
@decorator
def baybay():
print('拜拜~')
baybay()
# 我来自装饰器
# 2
# 我来自装饰器
# 拜拜~
decorator(old)类似于这样的函数就是一个装饰器,通过装饰器可以不在修改原函数的情况下,对函数进行扩展
在开发中都是通过装饰器来扩展函数功能