Python高级函数4

5 函数式编程

(1) 定义:用一系列函数解决问题。
-- 函数可以赋值给变量,赋值后变量绑定函数。
-- 允许将函数作为参数传入另一个函数。
-- 允许函数返回一个函数。

(2) 高阶函数:将函数作为参数或返回值的函数。

5.1 函数作为参数

将核心逻辑传入方法体,使该方法的适用性更广,体现
了面向对象的开闭原则。
list01 = [342, 4, 54, 56, 6776]
# 定义函数,在列表中查找所有大于100的数
def get_number_gt_100():
	for number in list01:
		if number > 100:
			yield number
# 定义函数,在列表中查找所有偶数
def get_number_by_even():
	for number in list01:
		if number % 2 == 0:
			yield number
# 参数:得到的是列表中的元素
# 返回值:对列表元素判断后的结果(True False)
def condition01(number):
	return number > 100
def condition02(number):
	return number % 2 == 0
# 通用函数
def find_all(condition): # 抽象
	for item in list01:
		# if number > 100:
		# if condition01(item):
		# if condition02(item):
		if condition(item):# 统一
			yield item
			# 变化点函数:查找小于10的数据
def condition03(number):
	return number < 10
for item in find_all(condition03):
	print(item)
练习1:
需求:
定义函数,在列表中查找奇数
定义函数,在列表中查找能被3或5整除的数字
步骤:
 -- 根据需求,写出函数。
 -- 因为主体逻辑相同,核心算法不同.
 所以使用函数式编程思想(分、隔、做)
创建通用函数find_all
-- 在当前模块中调用

练习2:
需求:
定义函数,在员工列表中查找编号是1003的员工
定义函数,在员工列表中查找姓名是孙悟空的员工
步骤:
 -- 根据需求,写出函数。
-- 因为主体逻辑相同,核心算法不同.
 所以使用函数式编程思想(分、隔、做)
创建通用函数find_single
 -- 在当前模块中调用
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(1002, 9001, "孙悟空", 50000),
	Employee(1003, 9002, "猪八戒", 20000),
	Employee(1004, 9001, "沙僧", 30000),
	Employee(1005, 9001, "小白龙", 15000),
]

5.1.1 lambda 表达式

(1) 定义:是一种匿名方法

(2) 作用:
-- 作为参数传递时语法简洁,优雅,代码可读性强。
-- 随时创建和销毁,减少程序耦合度。

(3) 语法
# 定义:
变量 = lambda 形参: 方法体

# 调用:
变量(实参)
(4) 说明:
-- 形参没有可以不填
-- 方法体只能有一条语句,且不支持赋值语句。

(5) 演示:
from common.iterable_tools import IterableHelper
# 定义函数,在列表中查找所有大于100的数
# def condition01(number):
# return number > 100
# 定义函数,在列表中查找所有偶数
# def condition02(number):
# return number % 2 == 0
list01 = [342, 4, 54, 56, 6776]
for item in IterableHelper.find_all(list01,lambda number: number > 100):
	print(item)
for item in IterableHelper.find_all(list01,lambda number: number % 2 == 0):
	print(item)

5.1.2 内置高阶函数

(1) map(函数,可迭代对象):使用可迭代对象中
的每个元素调用函数,将返回值作为新可迭代对象元
素;返回值为新可迭代对象。

(2) filter(函数,可迭代对象):根据条件筛选可
迭代对象中的元素,返回值为新可迭代对象。

(3) sorted(可迭代对象,key = 函数,
reverse = bool值):排序,返回值为排序结果。

(4) max(可迭代对象,key = 函数):根据函数获取
可迭代对象的最大值。

(5) min(可迭代对象,key = 函数):根据函数获取
可迭代对象的最小值。

(6) 演示:
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(1002, 9001, "孙悟空", 50000),
	Employee(1003, 9002, "猪八戒", 20000),
	Employee(1004, 9001, "沙僧", 30000),
	Employee(1005, 9001, "小白龙", 15000),
]
# 1. map 映射
# 需求:获取所有员工姓名
for item in map(lambda item: item.name, list_employees):
	print(item)
	
# 2. filter 过滤器
# 需求:查找所有部门是9002的员工
for item in filter(lambda item: item.did == 9002, list_employees):
	print(item.__dict__)
	
# 3. max min 最值
emp = max(list_employees, key=lambda emp: emp.money)
	print(emp.__dict__)
	
# 4. sorted
# 升序排列
new_list = sorted(list_employees, key=lambda emp: emp.money)
print(new_list)

# 降序排列
new_list = sorted(list_employees, key=lambda emp: emp.money, reverse=True)
print(new_list)
练习:
-- 在商品列表,获取所有名称与单价
-- 在商品列表中,获取所有单价小于10000的商品
-- 对商品列表,根据单价进行降序排列
-- 获取元组中长度最大的列表 ([1,1],[2,2,2],
[3,3,3])
class Commodity:
	def __init__(self, cid=0, name="", price=0):
		self.cid = cid
		self.name = name
		self.price = price
list_commodity_infos = [
	Commodity(1001, "屠龙刀", 10000),
	Commodity(1002, "倚天剑", 10000),
	Commodity(1003, "金箍棒", 52100),
	Commodity(1004, "口罩", 20),
	Commodity(1005, "酒精", 30),
]

5.2 函数作为返回值

逻辑连续,当内部函数被调用时,不脱离当前的逻辑。

5.2.1 闭包

(1) 三要素:
-- 必须有一个内嵌函数。
-- 内嵌函数必须引用外部函数中变量。
-- 外部函数返回值必须是内嵌函数。

(2) 语法
# 定义:
def 外部函数名(参数):
	外部变量
	def 内部函数名(参数):
		使用外部变量
	return 内部函数名
# 调用:
变量 = 外部函数名(参数)
变量(参数)
(3) 定义:是由函数及其相关的引用环境组合而成
的实体。
(4) 优点:内部函数可以使用外部变量。
(5) 缺点:外部变量一直存在于内存中,不会在调用
结束后释放,占用内存。
(6) 作用:实现python装饰器。

(7) 演示:
def give_gife_money(money):
	print("获得", money, "元压岁钱")
	def child_buy(commodity, price):
		nonlocal money
		money -= price
		print("购买了", commodity, "花了", price, "元,还剩下", money)
	return child_buy
action = give_gife_money(500)
action("变形金刚", 200)
action("芭比娃娃", 300)
练习:使用闭包模拟以下情景:
在银行开户存入10000
购买xx商品花了xx元
购买xx商品花了xx元

5.2.2 函数装饰器decorator

(1) 定义:在不改变原函数的调用以及内部代码情况
下,为其添加新功能的函数。

(2) 语法
def 函数装饰器名称(func):
	def wrapper(*args, **kwargs):
		需要添加的新功能
		return func(*args, **kwargs)
	return wrapper
	
@ 函数装饰器名称
def 原函数名称(参数):
	函数体
	
原函数(参数)
(3) 本质:使用“@函数装饰器名称”修饰原函数,
等同于创建与原函数名称相同的变量,关联内嵌函数;
故调用原函数时执行内嵌函数。
	原函数名称 = 函数装饰器名称(原函数名称)
def func01():
	print("旧功能")
	
def new_func(func):
	def wrapper():
		print("新功能")
		func() # 执行旧功能
	return wrapper
	
# 新功能覆盖了旧功能
# func01 = new_func

# 调用一次外部函数(装饰器本质)
func01 = new_func(func01)
# 调用多次内部函数
func01()
func01()
(3) 装饰器链:
一个函数可以被多个装饰器修饰,执行顺序为
从近到远。

练习1:不改变插入函数与删除函数代码,为其增加
验证权限的功能
def verify_permissions():
	print("验证权限")
	
def insert():
	print("插入")
	
def delete():
	print("删除")
	
insert()
delete()
练习2:为sum_data,增加打印函数执行时间的功能.
	函数执行时间公式: 执行后时间 - 执行前时间
def sum_data(n):
	sum_value = 0
	for number in range(n):
		sum_value += number
	return sum_value
	
print(sum_data(10))
print(sum_data(1000000))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值