1. 高阶函数
·接收函数作为参数,或者将函数作为返回值返回的函数就是高阶函数
需求: 将一个制定列表中的偶数,保存到一个新的列表中返回
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def fn(list1):
new_list = []
for i in list1:
if i % 2 == 0:
new_list.append(i)
return new_list
r = fn(list1)
print(r)
输出
[2, 4, 6, 8, 10]
·
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def fn1(i):
if i % 2 == 0:
return True
def fn(fun, list1):
new_list = []
for i in list1:
if fun(i):
new_list.append(i)
return new_list
r = fn(fn1, list1)
print(r)
输出
[2, 4, 6, 8, 10]
2. 闭包
·将函数作为返回值也是高阶函数我们也称为闭包
·闭包的好处
1.通过闭包可以创建⼀些只有当前函数能访问的变量
2.可以将⼀些私有数据藏到闭包中
·行成闭包的条件
1.函数嵌套
2.将内部函数作为返回值返回
3.内部函数必须要使用到外部函数的变量
·注意点:由于闭包引用了外部函数的变量(参数), 则外部函数的变量没有及时释放,消耗内存
def fun_out(num1):
def fun_inner(num2):
r = num1 + num2
print(r)
return fun_inner
r = fun_out(1)
r(2)
r(3)
输出
3
4
·
def fun_out(num1):
def fun_inner(num2):
nonlocal num1
num1 = 10
r = num1 + num2
print(r)
print(num1)
fun_inner(2)
print(num1)
return fun_inner
r = fun_out(1)
r(2)
r(3)
输出
1
12
10
12
13
3.装饰器的引入
·我们可以直接通过修改函数中的代码来完成需求,但是会产生以下⼀些问题
1.如果修改的函数多,修改起来会比较麻烦
2.不方便后期的维护
3.这样做会违反开闭原则(ocp)
·程序的设计,要求开发对程序的扩展,要关闭对程序的修改
def add(a, b):
return a + b
def fn1():
print('我是fn1')
def fn(a, b):
print('函数开始执行')
r = add(a, b)
print('函数执行结束')
return r
r = fn(1, 2)
print(r)
输出
函数开始执行
函数执行结束
3
4.装饰器的使用
·通过装饰器,可以在不修改原来函数的情况下来对函数进行扩展
·在开发中,我们都是通过装饰器来扩展函数的功能的
def fn(fun):
def new_fun(*args, **kwargs):
print('函数开始执行')
r = fun(*args, **kwargs)
print('函数执行结束')
return r
return new_fun
@fn
def speak():
print('同学们好好学习啊')
speak()
输出
函数开始执行
同学们好好学习啊
函数执行结束
·
装饰器的语法糖写法
@fn 等价于 speak = fn(speak)
r = fn(fn1)
r()
5.推导式
·列表推导式
1.语法: [表达式 for 变量 in 旧列表 if 条件]
list1 = ['cheney', 'jerry', 'amy', '居然', 'tony', 'anny', 'james', '豆腐', 'wolf']
def fn():
pass
result = [name for name in list1 if len(name) > 4]
print(result)
输出
['cheney', 'jerry', 'james']
6.生成器
·第一种方式:推导式得到
1.gen = (表达式 for 变量 in 旧列表 if 条件)
·第二种方式:函数方式得到 通过yield关键字
generator = (i for i in range(10) if i % 3 == 0)
r = [i for i in generator]
print(r) # [0, 3, 6, 9]
1.当使用yield关键字之后,函数不再是函数,而是一个生成器
2.当程序执行到yield的时候,程序就会停止 和 input类似
3.生成器,会记住你之前取到的元素的位置,下一次继续去数据的时候,他会在那个位置继续往下取数据
def fn():
print('fn执行了')
i = 1
while True:
yield i
i += 1
r = fn()
print(r)
print(next(r))
print(next(r))
print(next(r))
print(next(r))
输出
<generator object fn at 0x0000023701031CA8>
fn执行了
1
2
3
4