函数下
1. 高阶函数
-
接收函数作为参数,或者将函数作为返回值返回的函数就是高阶函数
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] def fun1(i): if n % 2 == 0: return True def fun2(n) if n > 5: return True def fun(fun, list1): #fun形参为函数对象 list2 = [] for i in list1: if fun(i): list2.append(i) return list2 print(fun(fun1, list1)) #第一个实参为函数对象
2. 匿名函数
函数过滤规则太过于简单时,为了减少函数命名,可以使用匿名函数
lambda函数 用来做一些简单的运算,而不用定义函数
语法: (lambda 参数列表:运算)(实参)
print((lambda a, b: a + b)(10, 20))
r = lambda a, b: a + b
print(r(10, 20))
#运行结果为:
30
30
3. 闭包
-
将函数作为返回值也是⾼阶函数我们也称为闭包
-
闭包的好处
- 通过闭包可以创建⼀些只有当前函数能访问的变量
- 可以将⼀些私有数据藏到闭包中
-
⾏成闭包的条件
-
函数嵌套
-
将内部函数作为返回值返回
def fun() def fun1() pass return fun1
-
内部函数必须要使⽤到外部函数的变量
def fun_out(num1): def fun_inner(num2): res = num1 + num2 return res return fun_inner r = fun_out(1) # fun_out(1) = fun_inner print(r(2)) #fun_out(1)() = fun_inner()
-
-
结论:闭包里面的外部函数的变量可以保证不被销毁,闭包要慎用
-
在闭包中修改外部函数的变量
# 变量不可被更改 # 让外部变量可以修改 def func_out(num1): def func_inner(num2): # 告诉解释器,此处使用的是外部变量num1 nonlocal num1 # 这里的本意是要修改外部变量num1的值,实际上是重新进行了赋值 num1 = 10 result = num1 + num2 print(result) print(num1) func_inner(2) print(num1) return func_inner f = func_out(1) # 函数对象是func_out 函数调用是func_out()
4. 装饰器的引入
-
我们可以直接通过修改函数中的代码来完成需求,但是会产⽣以下⼀些问题
- 如果修改的函数多,修改起来会⽐较麻烦
- 不⽅便后期的维护
- 这样做会违反开闭原则(ocp)
- 程序的设计,要求开发对程序的扩展,要关闭对程序的修改
def fun1(): print('我是fun1函数') def add(a, b): return a + b def mul(a, b): return a * b # 函数嵌套 # 将内部函数作为返回值返回 # 内部函数必须要使用到外部函数的变量 def fun(fn, *args, **kwargs): print('函数开始执行') r = fn(*args, **kwargs) print(r) print('函数执行完毕') fun(add, 1, 2)
5. 装饰器的使⽤
-
通过装饰器,可以在不修改原来函数的情况下来对函数进⾏扩展
-
在开发中,我们都是通过装饰器来扩展函数的功能的
# 通用装饰器 def fun_out(old): def fun_inner(*args, **kwargs): # 万能写法 print('程序开始执行了') print(old(*args, **kwargs)) print('程序执行结束了') return fun_inner @fun_out # @fun_out=fun_out(old) def fun1(): print('我是fun1') fun1() #输出结果为: 程序开始执行了 我是fun1 None 程序执行结束了 @fun_out def add(a, b): return a + b add(1, 2) #输出结果为: 程序开始执行了 3 程序执行结束了
6. 作业
请使用装饰器实现一存在函数的执行所花费的时间
.time模块
from time import time
def showTime(fn):
def show(*args, **kwargs):
start = time()
fn(*args, **kwargs)
end = time()
print('计算完成,总共耗时{}秒'.format(end-start))
return show
@showTime
def adds(a):
num = 0
for i in range(a):
num += i
print('从1开始相加至{}后的和是{}'.format(a,num))
adds(345678)
#输出结果为:
从1开始相加至345678后的和是59746467003
计算完成,总共耗时0.02699446678161621秒