函数下
1. ⾼阶函数
接收函数作为参数,或者将函数作为返回值返回的函数就是⾼阶函数
2. 闭包
1.将函数作为返回值也是⾼阶函数我们也称为闭包
2.闭包的好处
(1)通过闭包可以创建⼀些只有当前函数能访问的变量
(2)可以将⼀些私有数据藏到闭包中
3.⾏成闭包的条件
(1)函数嵌套
(2)将内部函数作为返回值返回
(3)内部函数必须要使⽤到外部函数的变量
3. 装饰器的引⼊
1.我们可以直接通过修改函数中的代码来完成需求,但是会产⽣以下⼀些问题
(1)如果修改的函数多,修改起来会⽐较麻烦
(2)不⽅便后期的维护
(3)这样做会违反开闭原则(ocp)
2.程序的设计,要求开发对程序的扩展,要关闭对程序的修改
4. 装饰器的使⽤
1.通过装饰器,可以在不修改原来函数的情况下来对函数进⾏扩展
2.在开发中,我们都是通过装饰器来扩展函数的功能的
高阶函数
# 接收一个或者多个函数对象作为参数。或者将的函数就是⾼阶函数
# 讲函数作为返回值返回
# 将一个指定的列表中的偶数,保存到一个新的列表中返回
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# def fun():
#
# # 在循环外创建一个空列表
# list2 = []
# for i in list1:
# # 判断 i奇偶
# if i % 2 == 0:
# list2.append(i)
#
# return list2
#
#
# print(fun())
def fun2(n):
if n % 2 == 0:
return True
def fun1(fn):
list2 = []
for i in list1:
# ??i???
if fn(i):
list2.append(i)
return list2
print(fun1(fun2))
匿名函数
# 匿名函数:就是没有名字的函数,不指定函数的名字。
# lambda函数语法: (lambda 参数:表达式)(传参)
# res = lambda a, b: a + b
# print(res(1, 2))
#
# res = (lambda a, b: a + b)(1, 2)
# print(res)
# filter()函数 过滤 两个参数
# 1. 传递一个参数
# 2. 传递一个需要过滤的序列
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def fun2(n):
if n % 2 == 0:
return True
# print(list(filter(fun2, list1)))
def fun3():
for i in list1:
if i % 3 == 0:
pass
def fun3():
pass
res = lambda i: i % 2 == 0
print(list(filter(res, list1)))
闭包
# • 行成闭包的条件
# • 函数嵌套
# • 将内部函数作为返回值返回 返回的是函数对象
# • 内部函数必须要使用到外部函数的变量或参数
# 闭包的作用: 保存外部函数的变量不被销毁
def fun_out(num1):
# 定义一个内部函数
def fun_inner(num2):
# 内部函数用到了外部函数的变量或参数(num1)
res = num1 + num2
print(res)
print(fun_inner.__closure__)
print(id(num1))
fun_inner(2)
print(id(num1))
return fun_inner
f = fun_out(1)
print(id(fun_out))
f(3)
# 修改外部变量
# def fun_out(num1):
# # 定义一个内部函数
# def fun_inner(num2):
# # 内部函数用到了外部函数的变量或参数(num1)
# # nonlocal num1 # 告诉解释器,此处用的是外部的变量num1 这是闭包的特性
# num1 = 2
# res = num1 + num2
# print(res)
#
# print(num1)
# fun_inner(2)
# print(num1)
#
# return fun_inner
#
#
# f = fun_out(1)
#
# f(3)
# 闭包会保持外部函数变量不被销毁, python内存容易满 慎用
装饰器的引入
def add(a, b):
return a + b
def qiuji():
print(111)
# fun是做装饰 并不是装饰器
def fun(fn, *args, **kwargs):
print('程序开始执行')
r = fn(*args, **kwargs)
print('程序执行结束')
return r
print(fun(add, 1, 2))
装饰器的创建和使用
# 装饰器是一个特殊的闭包
# 符合闭包的三大构成条件
# 通用装饰器
def fun_out(fn):
def fun_inner(*args, **kwargs):
print('函数开始执行')
r = fn(*args, **kwargs)
print('函数执行结束')
return r
return fun_inner
@fun_out # 装饰器语法糖的写法
def add(a, b):
return a + b
r = add(1, 2)
print(r)
@fun_out
def qiuji():
print(111)
qiuji()
# f = fun_out(add)
# r = f(1, 2)
# print(r)
# 语法糖: @fun_out 等价于 fun_out(fn)
第⼗讲作业
- 请使⽤装饰器实现已存在的函数的执⾏所花费的时间。
import time
def fun1(func):
def fun2(*args, **kwargs):
t = time.time()
res = func(*args, **kwargs)
print(res)
print(time.time() - t)
return res
return fun2
@fun1
def add_(a):
aa = 0
for i in range(int(a)):
aa += 1
return aa
add_(1000000)