定义:用一系列函数解决问题
–函数可以赋值给变量,赋值后变量绑定函数
–允许将函数作为参数传入另一个函数
–允许函数返回一个函数
高阶函数:
将函数作为参数或返回值的函数
适用性:
多个函数,主体逻辑相同,但核心算法不同.
步骤:
1."封装"[分]:根据需求将多个变化点分别定义到函数中
2."继承"[隔]:将变化的函数抽象为参数
在通用函数中先确定参数的使用方式
隔离了通用函数与变化函数
3."多态"[做]:按照通用函数中确定的使用方式,创建变化函数.
list01 = [36, 1000, 65, 90, 7, 8, 9,1]
# 需求:查找第一个小于10的数字
"""
def find_single_lt_10():
for item in list01:
if item < 10:
return item
# 需求:查找第一个大于20的数字
def find_single_gt_20():
for item in list01:
if item > 20:
return item
"""
# 变化
def condition01(item):
return item < 10
def condition02(item):
return item > 20
# 不变(通用函数)
def find_single(condition):
for item in list01:
# if item < 10:
# if condition01( item ):
# if condition02( item ):
# 统一使用方法
if condition(item):
return item
# 新增查找奇数的需求
def condition_new(item):
return item % 2 != 0
print(find_single(condition_new))
print(find_single(condition01))
print(find_single(condition02))
定义:
@staticmethod
def 方法名称(参数):
方法体
调用:
类名.方法名称(参数)
说明
使用@staticmethod修饰的目的是该方法不需要隐式传参数
静态方法不能访问实例成员和类成员
作用:定义常用的工具函数
"""
可迭代对象工具集
"""
class IterableHelper:
"""
可迭代对象助手类:对可迭代对象常用的高阶函数
"""
# 静态方法:不操作实例成员/类成员
@staticmethod
def find_single(iterable, condition):
"""
在可迭代对象中,查找满足条件的第一个元素
:param iterable: 可迭代对象
:param condition: 函数类型的查找条件
:return: 满足条件的第一个元素
"""
for item in iterable:
if condition(item):
return item
@staticmethod
def find_all(iterable,condition):
"""
在可迭代对象中,查找满足条件的所有元素
:param iterable: 可迭代对象
:param condition: 函数类型的查找条件
:return: 生成器,推算满足条件的元素
"""
for item in iterable:
if condition(item):
yield item
@staticmethod
def sum(iterable,condition):
"""
在可迭代对象中,查找条件累加
:param iterable: 可迭代对象
:param condition: 函数类型的累加条件
:return: 数值类型,累加和
"""
sum_value = 0
for item in iterable:
sum_value += condition(item)
return sum_value
@staticmethod
def delete_all(iterable,condition):
"""
:param iterable:
:param condition:
:return:
"""
count = 0
for i in range(len(iterable) - 1, -1, -1):
if condition(iterable[i]):
del iterable[i]
count += 1
return count
@staticmethod
def select(iterable,condition):
"""
在可迭代对象中根据条件选择成员
:param iterable: 可迭代对象
:param condition: 函数类型的选择策略
:return: 生成器,推算出元素的成员
"""
for item in iterable:
yield condition(item)
@staticmethod
def get_count(iterable,condition):
"""
在可迭代对象中计算满足条件的元素数量
:param iterable: 可迭代对象
:param condition: 函数类型的条件
:return: int类型,数量
"""
count = 0
for item in iterable:
if condition(item):
count += 1
return count
@staticmethod
def get_max(iterable, condition):
"""
在可迭代对象中,根据条件查找
:param iterable: 可迭代对象
:param condition: 函数类型,查找策略
:return: 最大值
"""
max_value = iterable[0]
for i in range(1, len(iterable)):
if condition(max_value) < condition(iterable[i]):
max_value = iterable[i]
return max_value
@staticmethod
def is_repeat(iterable, condition):
"""
在可迭代对象中根据条件判断是否有重复的元素
:param iterable: 可迭代对象
:param condition: 函数类型,判断条件
:return: bool类型,True表示有重复,Flase表示没有重复
"""
for r in range(len(iterable) - 1):
for c in range(r + 1, len(iterable)):
if condition(iterable[r]) == condition(iterable[c]):
return True
return False
@staticmethod
def order_by(iterable, condition):
"""
根据条件对可迭代对象升序排列
:param iterable: 可迭代对象
:param condition: 函数类型,排序依据
"""
for r in range(len(iterable) - 1):
for c in range(r + 1, len(iterable)):
if condition(iterable[r]) > condition(iterable[c]):
iterable[r], iterable[c] = iterable[c], iterable[r]
注意1:lambda函数体只能有一条语句
注意2:lambda不支持赋值语句
lambda 匿名方法
语法:
lambda 参数:函数体
lambda能完成的功能,def都能完成
但是lambda函数体只能有一条语句且不能是赋值语句
lambda作用
作为函数实参
map
filter
min
sorted
sort
"""
内置高阶函数
"""
from common.iterable_tools import IterableHelper
class Employee:
def __init__(self, eid, did, name, money):
self.eid = eid # 员工编号
self.did = did # 部门编号
self.name = name
self.money = money
list_employees = [
Employee(1001, 9002, "师父", 60000),
Employee(1004, 9001, "沙僧", 30000),
Employee(1003, 9002, "猪八戒", 20000),
Employee(1002, 9001, "孙悟空", 50000),
Employee(1002, 9001, "孙悟空", 120000),
Employee(1005, 9001, "小白龙", 15000),
]
# 需求:获取所有员工姓名
# IterableHelper.select()
# map:映射
for name in map(lambda e:e.name,list_employees):
print(name)
# 需求:获取所有月薪小于20000的员工
# IterableHelper.find_all()
# filter:筛选器
for emp in filter(lambda item:item.money < 20000,list_employees):
print(emp.__dict__)
# 需求:获取所有月薪最小的员工
# IterableHelper.get_max()
# min:最小 max:最大
emp = min(list_employees,key = lambda e:e.money)
print(emp.__dict__)
# sorted 排序:
# 注意:返回新列表,不改变原有列表
# - 升序排列
new_list = sorted(list_employees,key =lambda e:e.did )
# - 降序排列
new_list = sorted(list_employees,key =lambda e:e.did,reverse=True)
for item in new_list:
print(item.__dict__)
# 注意:修改原列表
list_employees.sort(key =lambda e:e.did )
"""
外部嵌套作用域 :函数嵌套。
"""
def func01():# 外函数
a = 10 # 局部变量/外部嵌套变量
b = 20
def func02():# 内函数
# 可以读取外部嵌套变量
print(a)
# 如果修改必须先通过nonlocal声明
nonlocal b
b = 200
func02()
print(b)
func01()
三要素:
必须有一个内嵌函数
内嵌函数必须引用外部函数中变量
外部函数返回值必须是内嵌函数
作用:
外部函数调用后,栈帧保留,供内部函数不断使用
def func01():
a = 10
def func02():
print(a)
return func02
# 调用外函数,接收内函数
result = func01()
# ...
# 调用内函数
result()
内函数的返回值:旧功能的返回值
在不改变旧功能调用与定义的情况下,
为其增加新功能
闭包三大要素在装饰器中的作用:
有外有内:外在接收旧功能,内函数包装新旧功能
内访问外:希望同时执行新旧功能
外返回内:日后根据需求执行新旧功能
def 函数装饰器名称(func):
def wrapper(*args,**kwargs):
需要添加的新功能
return func(*args,**kwargs)
return wrapper
@函数装饰器名称
def 原函数名称(参数):
函数体
原函数(参数)
本质:使用"@函数装饰器名称"修饰原函数,等同于创建与原函数名称相同的变量,关联内嵌函数;故调用原函数时执行内嵌函数
原函数名称 = 函数装饰器名称(原函数名称)
def func01():
print("旧功能")
def func_new(func):
def wrapper():
print("新功能")
res = func()
return res
return wrapper # 返回内函数
# 调用外函数(不执行内函数)
func01 = func_new(func01)
# 调用内函数
func01()
# ....
func01()
"""
装饰器 - 标准
内函数的返回值:旧功能的返回值
调用外函数,作为参数传进去,返回值重新给函数赋值
"""
def func_new(func):
def wrapper(*args):# 2 合
print("新功能")
res = func(*args) # 调用旧功能 拆
return res
return wrapper
# func01 = func_new(func01)
@func_new
def func01(p1):# 3
print("旧功能1")
return 100
@func_new
def func02(p1,p2):# 3
print("旧功能2")
# func01 = func_new(func01)
# func02 = func_new(func02)
# 1
value = func01(10) # 调用内函数
value = func02(10,20) # 调用内函数
print(value)