函数(3)
1.1 高阶函数
1 满足2个条件任意一个都是高阶函数
接收函数作为参数的函数
将函数作为返回值的函数
2 当我们使用一个函数作为参数时,实际上我们就是将指定的代码传递给了目标函数
下面设置几个函数,然后进行接收
# 定义一个函数,用于检测数字是否是偶数
def fn2(i):
if i % 2 == 0:
return True
return False
# 定义一个函数 用来检测指定数字是否大于5
def fn3(i):
if i > 5:
return True
return False
# 定义一个函数 用来检测3的倍数
def fn4(i):
if i % 3 == 0:
return True
return False
l = [1,2,3,4,5,6,7,8,9,10]
# 定义一个函数 可以将指定的列表的符合条件的元素保存到一个新的列表并返回fun
def fn(func,lst):
new_list = []
for n in lst:
if func(n):
new_list.append(n)
return new_list
a = fn(fn2,l)# 用于输出是偶数的数
print(a)
a = fn(fn3,l)# 用于输出大于五的数
print(a)
a = fn(fn4,l)# 用于输出是3的倍数的数
print(a)
运行结果
[2, 4, 6, 8, 10]
[6, 7, 8, 9, 10]
[3, 6, 9]
1.2 匿名函数
一 匿名函数 lambda表达式
1 lambda函数表达式是用来创建一些简单的函数 它是函数创建的另外一种方式
语法: lambda 参数列表 : 返回值
2 匿名函数最大的好处是只会调用一次,用完之后会从内存中消失
3 匿名函数一般都是作为参数使用
def fn5(a,b):
return a + b
print(fn5(1,2))
print((lambda a,b : a + b)(5,2)) # 使用lambda函数
# 将匿名函数赋值个一个变量
fn6 = lambda a,b : a + b
print(fn6(20,50))
运行结果
3
7
70
二 filter() 可以从序列中过滤出符合条件的元素,保存到一个新的序列当中
参数: 1.函数,根据该函数来过滤序列(可迭代结构)
需要过滤的序列(可迭代结构)
返回值 过滤后新的序列
语法结构
filter(func,可迭代序列)
l = [1,2,3,4,5,6,7]
def fn2(i):
if i % 2 == 0:
return True
r = filter(fn2,l) # 将返回序列设置为变量r
print(tuple(r)) # 将r转化为元组
print(list(r)) # 将r转化为列表
运行结果
(2, 4, 6)
[]
三 map()函数
1 map()函数可以对可迭代对象中所有元素做指定的操作,然后将其添加到一个新的对象中返回
2 语法结构
map(func,可迭代对象)
l = [1,2,3,4,5,6,7,8,9,10]
r = map(lambda i : i + 1,l) # 将lambda函数作为参数
print(list(r))
d = {'name':1,'age':20,'phone':13246}
r = map(lambda i : i + 1,d.values()) # 将字典中的value作为可迭代对象
print(list(r))
运行结果
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
[2, 21, 13247]
1.3 闭包
1 将函数作为返回值返回,也是一种高阶函数
2 通过闭包可以换创建一些只有当前函数才能访问的对象,还可以将一些私有的数据藏到闭包中
3 形成闭包的条件
- 函数嵌套
- 将内部函数作为返回值返回
- 内部函数必须使用到外部函数的变量
def new_avg():
# 创建一个列表 用来保存数据
nums = []
def avg(n):
# 将元素添加到列表当中
nums.append(n)
print(nums)
# 求平均值
return sum(nums)/len(nums)
return avg # 返回函数avg所以是高阶函数
a = new_avg()
print(a(10))
print(a(10))
print(a(30))
nums = []
print(nums)
运行结果
[10] # 第一次将10添加到列表nums[]当中
10.0 # 第一次求平均值
[10, 10] # 第二次将10添加到列表nums[]当中
10.0 # 第一次求平均值
[10, 10, 30] # 第三次将10添加到列表nums[]当中
16.666666666666668 # 第一次求平均值
[] # 函数中的列表nums与函数外的无关
1.4 装饰器的引入
我们可以通过修改函数中的代码来完成,但是会产生一些问题
1.修改的函数很多
2.不方便后期的维护
3.会违反开闭原则(ocp) 程序设计 要求对程序的扩展,但是要关闭对程序的修改
所以引进装饰器
1 通过装饰器可以在不修改原函数的情况下对函数进行扩展
2 在开发当中,都是通过装饰器来扩展函数的功能
例一: 不修改原函数,来对函数进行扩展
def fn():
print('我是fn函数')
# 来创建一个新的函数 来对原函数进行扩展
def fn2():
print('函数开始执行')
fn()
print('函数执行结束')
fn2()
运行结果
函数开始执行
我是fn函数
函数执行结束
例二:对add()函数进行扩展
def add(a,b):
return a + b
def new_add(a,b):
print('函数开始执行')
r = add(a,b)
print('函数执行结束')
return r
r = new_add(1,2)
print(r)
运行结果
函数开始执行
函数执行结束
3
1.5 装饰器的使用
一:
def add(a,b):
return a + b
def start_end(old):
# 参数 old 要扩展的函数对象
# 用来对其他的函数进行扩展 函数开始执行 函数执行结束
# 创建一个新的函数
def new_function(*args,**kwargs):
# 当不知到参数的数量十,将位置参数和特殊值参数分别装包为元组和字典
# 此时的*args,**kwargs为装包
print('函数开始执行')
result = old(*args,**kwargs)
# 此时的*args,**kwargs为解包
# 将元组以及字典解包
print('函数执行结束')
# 返回函数执行结果
return result
# 返回新函数
return new_function
f = start_end(add)
r =f(1,2)
print(r)
print(f)
运行结果
函数开始执行
函数执行结束
3
<function start_end.<locals>.new_function at 0x000001CCFC1A0E18>
二:
def start_end(old):
def new_function(*args,**kwargs):
print('函数开始执行')
r = old(*args,**kwargs)# 此函数没返回值的话,作为函数的函数也没返回值
#return r
print('函数执行结束')
return new_function
@start_end
def add(a,b):
c = a + b
print(c)
return c # 返回在这得提前设置
r = add(1,2)
print(r)
运行结果
函数开始执行
3
函数执行结束
None