python中函数的介绍(三)
一、高阶函数
- 高阶函数的特点:
- 1.接收一个或多个函数作为参数。
- 2.将函数作为返回值返回
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def fun1(i):
if i % 2 == 0:
return True
def fun(fun1, list1):
list2 = []
for i in list1:
if fun1(i):
list2.append(i)
return list2
print(fun(fun1, list1))
二、匿名函数
1、filter()的用法
- filter() 需要传递两个参数,按照设定的规则,过滤出想要的数据
- 1.传递一个函数
- 2.传递一个需要过滤的序列(可迭代的)
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def fun1(i):
if i % 2 == 0:
return True
f = filter(fun1, list1)
print(f) # <filter object at 0x00000282885682E8>
print(list(f)) # [2, 4, 6, 8, 10]
2、lambda()函数的用法
- 匿名函数:lambda函数,就是专门来创建一些简单的函数
- 语法:lambda 参数:表达式
# - filter() 需要传递两个参数,按照设定的规则,过滤出想要的数据
# - 1.传递一个函数
# - 2.传递一个需要过滤的序列(可迭代的)
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def fun1(i):
if i % 2 == 0:
return True
f = filter(fun1, list1)
print(f) # <filter object at 0x00000282885682E8>
print(list(f)) # [2, 4, 6, 8, 10]
# 匿名函数:lambda函数,就是专门来创建一些简单的函数
# 语法:lambda 参数:表达式
r = lambda a, b: a + b
print(r(10, 20)) # 的打印结果为30
# filter 与 lambda函数结合使用
result = lambda i: i % 2 == 0
print(list(filter(result, list1))) # [2, 4, 6, 8, 10]
三、闭包
- 将函数作为返回值也是高阶函数,我们也称为闭包
- 闭包的好处:
1.通过闭包可以创建一些只有当前函数能访问的变量
2.可以将一些私有数据藏到闭包中 - 形成闭包的条件
1.函数嵌套
2.将内部函数作为返回值返回
3.内部函数必须要使用到外部函数的变量
# 变量不被销毁
def func_outter(num1):
def func_inner(num2):
result = num1 + num2
print(result)
return func_inner
f = func_outter(1)
f(2) # 打印结果为 3
f(3) # 4 说明num1 没有被销毁
# 变量不可被更改
def func_outter(num1):
def func_inner(num2):
num1 = 10
result = num1 + num2
print(result)
print(num1) # 调用之前 打印结果为1
func_inner(1)
print(num1) # 调用之后 打印结果为1
return func_inner
func_outter(1)
打印结果
1
11
1
解释:
为什么会出现这样的打印结果呢?
是因为调用了func_inner(1)函数时,又将在里面重新赋值了num1 = 10,而这时的num1与外部函数的num1 时没有任何关系的,只是名字像同罢了,而且,在调用了func_inner(1)函数之后,func_inner(1)内部的参数都会被销毁,而这时打印num1时,系统会默认是外部函数中的参数。所以打印结果为1。
那如果我们想更将内部函数变为可以更改怎么办呢?用下面这个方法!
# 将内部变量修改 用nonlocal
def func_outter(num1):
def func_inner(num2):
nonlocal num1 # 将num1定义为外部变量
num1 = 10
result = num1 + num2
print(result)
print(num1) # 调用之前 打印结果为1
func_inner(1)
print(num1) # 调用之后 打印结果为1
return func_inner
func_outter(1)
四、装饰器
1、装饰器的引入
- 为什么要引入装饰器?
如果我们想在已经存在的函数中添加一些新的功能,那么,我们可以直接修改已经存在的函数中的代码来完成添加,但是会产生一些问题:如果修改的函数多,修改起来会很麻烦、不方便后期的维护、这样做会违反开闭原则(ocp)
# 为什么要引入装饰器?
# 如果我们想在已经存在的函数中添加一些新的功能,那么,我们可以直接修改已经存在的函数中的代码来完成添加,但是会产生一些问题:如果修改的函数多,修改起来会很麻烦、不方便后期的维护、这样做会违反开闭原则(ocp)
# 例如:
def fun1(a, b):
return a + b
def fun2(a, b):
return a * b
def fun3(fun, *args, **kwargs):
print('函数开始执行')
r = fun(*args, **kwargs)
print(r)
print('函数执行结束')
fun3(fun1, 1, 2) # 将函数fun1添加到fun3中
fun3(fun2, 1, 2) # 将函数fun2添加到fun3中
# 这样做很麻烦,当我们引入装饰器时,问题会简单许多
2、装饰器的使用
- 在闭包的条件下使用
- 通过装饰器,可以在不修改原来函数的情况下来对函数进行扩展
- 在开发中,我们都是通过装饰器来扩展函数的功能的
# 通过装饰器,可以在不修改原来函数的情况下来对函数进行扩展
# 在开发中,我们都是通过装饰器来扩展函数的功能的
# 在闭包的条件下使用
def func_outter(fun, *args, **kwargs):
def func_inner(*args, **kwargs):
print('函数开始执行')
r = fun(*args, **kwargs)
print(r)
print('函数结束执行')
return func_inner
@func_outter # 将下面的fun1()添加到func_outter()中
def fun1():
print('这是函数fun1')
fun1()
@func_outter # # 将下面的fun2()添加到func_outter()中
def fun2(a, b):
return a * b
fun2(1, 2)
打印结果:
函数开始执行
这是函数fun1
None
函数结束执行
函数开始执行
2
函数结束执行
五、作业
- 1.请使用装饰器实现已存在的函数的执行所花费的时间。
• time模块
# 1. 请使用装饰器实现已存在的函数的执行所花费的时间。
# • time模块
import time
def fun1(fun, *args, **kwargs):
def fun2(*args, **kwargs):
list1 = []
for i in range(1, 10000000):
if i % 2 == 0:
list1.append(i)
fun(*args, **kwargs)
return fun2
start = time.time()
@fun1
def func_time():
end = time.time()
print('Running time: %s Seconds' % (end - start))
print(func_time()) # Running time: 0.8337688446044922 Seconds