高阶函数
1.map()
map:映射
map(func,iterable),返回值是一个iterator【容器,迭代器】
func:函数
iterable:可迭代对象【容器】,可以是多个,常用列表
功能:将iterable容器中的每一个元素传参给func,func会返回一个结果,结果会成为iterator中的元素
容器----》func----》新的容器
2.reduce()
reduce:减少
reduce(func,seq)
func:函数
seq:序列【容器】
功能:
首先将seq中的第0个元素和第1个元素传递给func,进行运算,返回结果1
接着,将 结果1 和第2个元素传递给func,进行运算,返回结果2
接着,将 结果2 和第3个元素传递给func,进行运算,返回结果3
…
直到所有的元素全部参与运算,表示运算结束
3.filter()
filter(func,iterable):过滤
func:函数
iterable:可迭代对象
功能:将iterable中的元素依次传递给func,根据func的返回值决定是否保留该元素,
如果func的返回值为True,则表示当前元素需要保留,如果为False,则表示过滤
4.sorted()
【面试题】列表中的sort函数和高阶函数sorted的区别和联系
1.调用语法:
列表.sort(reverse,key=func),
sorted(iterable,reverse,key=func)
2.结果:sort是在原列表内部排序的,sorted是生成了一个新的列表
3.二者默认情况下都是升序排序,如果要降序,则都是设置reverse=True
4.如果要自定义排序的规则,二者都是给key参数设置函数
装饰器
1.概念
概念:
已知一个函数,如果需要给该函数增加新的功能,但是不希望修改原函数,
在Python中,这种在代码运行期间动态执行的机制被称为装饰器【Decorator】
- 装饰器的作用:为已经存在的函数或者类添加额外的功能
- 装饰器的本质:实际上就是一个闭包,内部函数访问外部函数中的变量【函数】
2.基本语法
# 需求:已知函数func,不修改原函数的基础上,增加一个新的功能
def func():
print("hello world")
# 1.基本语法
# a.书写闭包
# b.给外部函数设置参数,参数表示需要被装饰的函数,命名建议:f/fun/func
def outter(f):
def inner():
# c.调用被装饰的函数
f()
# d.增加新的功能
print('new~~~~~')
return inner
# e.调用装饰器【外部函数】
r = outter(func)
# f.调用装饰之后的结果【内部函数】
r()
# 注意:outter就是装饰器的名称,inner是在整个装饰器的核心
# 2.装饰器的执行顺序
def func(): # 1 11
print("hello world") # 12
def outter(f): # 2 4
def inner(): # 5 9
# 相当于原函数func()
f() # 10 13
print('new~~~~~') # 14
return inner # 6
# func--->f r---->inner
r = outter(func) # 3 7
# 相当于调用inner()
r() # 8 14
3.使用
a.
# 需求:给下面显示年龄的函数增加新的功能,对年龄完成校验
def get_age(age):
print(f"年龄:{age}")
def check_age(func):
def inner(n):
# 增加的新的功能
if n < 0:
n = abs(n)
elif n > 150:
n = 150
# 调用原函数
func(n)
return inner
r = check_age(get_age)
r(-18)
"""
说明:
a.在进行函数装饰的时候,调用原函数和增加新功能没有绝对的先后顺序,可以根据需求处理
b.如果原函数有参,在内部函数中增加新功能的时候,如果需要对原函数参数相关的数据进行运算
则需要给装饰器的内部函数设置参数,该参数表示从外部传递进来的值
"""
b.
# Python推荐使用@xxx方式使用装饰器
# @xxx:xxx表示装饰器的名称,只需要将@xxx作用于需要被装饰的函数的前面即可
# 注意:如果使用@xxx加载装饰器,则必须装饰器先存在,然后才能使用
def check_age(func):
print("外部函数!~~~~~~")
def inner(n):
print("inner~~~~~~~~~~")
# 增加的新的功能
if n < 0:
n = abs(n)
elif n > 150:
n = 150
# 调用原函数
func(n)
print('外部函数~~~~~over')
return inner
@check_age # 调用外部函数, 相当于r = check_age(get_age)
def get_age(age):
print(f"年龄:{age}")
# print(get_age)
get_age(-19) # 调用内部函数, 相当于r(-18)
"""
工作原理:
第一步:@check_age
将原函数get_age传参给func---->调用check_age---->get_age变量名指向inner
第二步:get_age(-19)
调用的是inner---->调用原函数
整个过程中用到了函数的本质:函数其实就是一个变量,函数名其实就是一个变量
说明:@xxx这种形式的装饰器的使用多数用于系统装饰器的使用中
"""
c.
# 需求:书写一个装饰器,可以装饰任意的函数
# 作用:给多个函数同时增加同一个功能,则需要给装饰器内部函数设置不定长参数,格式:*args,**kwargs
def wrapper(func):
print("wrapper")
def inner(*args,**kwargs): # 打包
print(args,kwargs)
# 调用原函数
func(*args,**kwargs) # 拆包
print('new~~~~~')
return inner
@wrapper
def f1():
print('1111111')
@wrapper
def f2(a,b):
print("222222",a,b)
@wrapper
def f3(num1,num2,num3,a,b):
print("33333",num1,num3,a,b)
f1() # inner()
f2(23,56) # inner()
f3(34,6,7,78,8) # inner
# a,b = (23,56) # a:23 b:56
【面试题】练习:书写一个装饰器,统计任意函数的执行时间
import time
def get_time(func):
def caculate(*args, **kwargs):
# 开始时间
start_time = time.time()
# 调用原函数
func(*args, **kwargs)
# 结束时间
end_time = time.time()
return round(end_time - start_time,5)
return caculate
@get_time
def f():
for n in range(1000000):
pass
r = f() # caculate()
print(r)