一.高阶函数
1.函数作为变量
"""
python中声明函数就是声明一个类型是function的变量,函数名就是变量名
普通变量能做的事情函数都能做
"""
1.声明函数就是声明变量,函数名就是变量名
def func1():
print('函数1')
return 100
print(type(func1))
2.普通变量能做的函数都可以做
1)一个变量可以给另一个变量赋值
例如:
a=100
b=a
print(b,b+100)
def func3():
print('函数3')
return 200
b2 = func3
print(type(b2),b2())
2)修改变量的值
a = 100
a = 'abc'
print(a,a[1:])
3)变量作为序列元素
a=10
list1 = [a,100,'abc']
print(list1)
def func4():
print('函数4')
return 400
list2=[func4,func4(),10]
print(list2)
print(list2[0]())
4)变量作为函数的参数
def func5(x):
print('函数5',x)
a = 100
func5(a)
func5(func4)
1.将函数作为函数的参数 - 实参高阶函数
def func4():
print('函数4')
return 400
def func6(x):
# x = func4
y=x() # func4()
# print('y:',y)
return y
# func6(a) - TypeError: 'int' object is not callable
re = func6(func4)
print(re)
2.系统的实参高阶函数
列表.sort(), sorted(), max(), min() 都是实参高阶函数,因为这四个函数中都有一个参数key,要求是一个函数
nums = [10,89,78,7]
nums.sort(reverse=True)
print(nums)
1)排序方法:参数key要求是一个函数,作用是用来定制排序的规则(默认按元素的大小从小到大或者从大到小排序)
参数key的要求:
a.key是一个函数
b.函数中有且只有一个函数,这个参数指向的是序列中的每个元素
c.函数需要一个返回值,这个返回值就是排序的时候比较大小的对象
nums = [100,39,51,62,58]
# 将nums中的元素按个位数从小到大排序
#def func_key(item):
# return item % 10
#
#nums.sort(key=func_key)
# 匿名函数做:
nums.sort(key=lambda item:item % 10)
print(nums)
# 将所有学生按学生排序
stu=[
{'name':'小明','age':'12','score':'98'},
{'name':'小王','age':'15','score':'96'},
{'name':'小花','age':'10','score':'97'}
]
def stu_key(item1):
return item1['score']
stu.sort(reverse=True,key=stu_key)
print(stu)
# 按学生年龄和分数的和从小到大排序
def stu_key2(item2):
return int(item2['age'])+int(item2['score'])
stu.sort(key=stu_key2)
print(stu)
# max/min 默认是直接比较序列元素的大小,求出最大/最小值
nums=[19,89,199,78,98]
# 求nums中个位数最大的元素
max2 = max(nums,key=lambda item:item % 10)
print(max2)
# max函数的原理
nums=[17,81,195,76,98]
# def yt_max(seq,key=None):
# t_seq = list(seq)
# yt_max = t_seq[0]
# if key:
# for item in t_seq[1:]:
# if item > yt_max:
# ty_max = item
# else:
# for item in t_seq[1:]:
# if key(item) > key(yt_max):
# ty_max = item
# return ty_max
max2=max(nums,key = lambda item:item % 10)
print(max2)
二.返回值高阶函数
# 函数作为函数的返回值 - 返回值高阶函数
# func1就是一个返回值高阶函数
def func1():
def func2():
print('函数2')
return func2
print(func1()) # <function func1.<locals>.func2 at 0x00000202CB929040>
func1()()
print('============')
print(func1()())
print('================================================')
# 2.闭包 - 在函数1中声明了函数2, 并且函数2中使用了函数1的数据
# 闭包的特点:闭包函数中的数据不会因为函数调用结束而销毁
def func3():
a=10
def func4():
print(a)
return func4
func3()
print('============')
t=func3()
t()
print(t)
print(t())
# 面试题1:
list1 = []
for i in range(5):
list1.append(lambda x: x*i)
print(list1[1](2),list1[2](2),list1[3](2))
# 面试题2:
def func2(seq=[]):
seq.append(10)
return seq
print(func2())
print(func2())
# print(func2())
print(func2)
print(func2(func2()))
# 练习:写出打印结果
list3=[1,2]
def func3(seq=list3):
seq.append(10)
return seq
func3()
# list3 = [100,200]
# print(func3())
list3.append(100)
print(func3())
三.装饰器
# 1.什么是装饰器
"""
装饰器本质是一个函数 = 返回值高阶函数 + 实参高阶函数 +糖语法
装饰器是python三大神器之一:装饰器,迭代器,生成器
作用:给已经写好的函数添加新的功能
"""
# 给函数添加一个功能:统计函数的执行时间
# 方法一:在每个需要添加功能的函数中加入相应代码
import time
def ys_sum(x,y):
start = time.time() #获取当前时间
sum1=x+y
print(sum1)
end = time.time()
print('函数执行时间:%fs'%(end - start))
ys_sum(100,200)
# 方法二:
# 注意:这个add_time只能给没有参数的函数添加统计执行时间的功能
def add_time(fn):
start = time.time()
fn()
end=time.time()
print('函数执行时间:%fs' % (end - start))
def func1():
return print('=========')
print('+++++++++++++')
add_time(func1)
def func3(x,y):
print('%d+%d=%d'%(x,y,x+y))
def add_time2(fn,*args,**kwargs):
start = time.time()
fn(*args,**kwargs)
end = time.time()
print('函数执行时间:%fs' % (end - start))
add_time2(func3,10,20)
print("==========2.装饰器==================2.装饰器")
# 方法三:装饰器
# 2.装饰器
"""
无参装饰器的函数:
def 函数名1(参数1):
def 函数名2(*args,**kwargs):
参数1()
新功能对应的代码段
return 函数名2
说明:
函数名1 - 装饰器的名字;一般根据需要添加的功能命名
参数1 - 需要添加功能的函数, 一般命名为fn
函数名2 - 随便命名,一般可以用test
"""
def add_time3(fn):
def test(*args,**kwargs):
start = time.time()
fn(*args, **kwargs)
end = time.time()
print('函数执行时间:%fs' % (end - start))
return test
@add_time3
def func5():
print('你好吗')
func5()
"""
无参装饰器的函数:
def 函数名1(参数1):
def 函数名2(*args,**kwargs):
参数1()
新功能对应的代码段
return 函数名2
说明:
函数名1 - 装饰器的名字;一般根据需要添加的功能命名
参数1 - 需要添加功能的函数, 一般命名为fn
函数名2 - 随便命名,一般可以用test
"""
# 练习:给所有返回值是整数的函数添加功能,返回值以16进制形式的数据返回
def zh16(fn):
def test(*args,**kwargs):
re=fn(*args, **kwargs)
# 判断re是否是整型
if type(re) == int:
# 或者 if isinstance(re,int):
return hex(re)
return test
@zh16
def ys_sum1(x,y):
return x+y
print(ys_sum1(10,20))
四.解包操作
"""
def test(*args, **kwargs):
re = fn(*args, **kwargs)
"""
# 1.解包:在容器型数据类型加*或者**可以对容器进行解包
# 注意:**只能放在字典的前面
list1 = [10,20,30]
print(*list1) #list1 == [10,20,30] -> *list1 == 10,20,30
def func1(x,y,z):
print('x:{},y:{},z:{}'.format(x,y,z))
func1(*list1)
# 练习:写一个函数可以对多个数据进行不同的运算
def ys_sum(*nums):
sum1 = 0
for x in nums:
sum1 += x
return sum1
def ys_sub(*nums):
sub1 = nums[0]
for y in nums[1:]:
sub1 -= y
return sub1
def math(op,*nums):
if op == '+':
return ys_sum(*nums)
if op == '-':
return ys_sub(*nums)
print(math('-',9,3,4))
print(math('+',1,2,3))
# 2)**是将字典解包
dict1={'x':100,'y':200}
print(dict1)
print(*dict1)
dict2={'end':'1','sep':'2'}
print(100,200,300,**dict2)
五.迭代器
# 1什么是迭代器(iter)
"""
也是python提供的容器型数据类型
迭代器存储数据的特点:一个迭代器可以存储多个数据,如果要获取元素,
必须将元素从迭代器中取出,而且取出一个就少一个,取出来的数据不能再添加到迭代器中
"""
# 2.将数据存入迭代器:
# 1)讲别的序列转换成迭代器 # 2)创建生成器
list1=[10,20,30]
iter1=iter(list1)
print(iter1)
iter2=iter('hello')
print(iter2)
# 3.获取迭代器中的元素
"""
迭代器中的元素不管通过什么方式取出来过,那么这个元素在迭代器中就不存在了
"""
# 1)获取单个元素
# next(迭代器) - 取出迭代器中最前面的元素
print(next(iter1))
print(next(iter1))
print(next(iter1))
# 2)遍历 - 一个一个的取所有元素
for x in iter2:
print('x:',x)