一、定义:
函数作为参数作用:将核心逻辑传入方法体,使该方法的适用性更广,体现了面向对象的开闭原则;
函数作为返回值作用:逻辑连续,当内部函数被调用时,不脱离当前的逻辑。
二、高阶函数:
1、定义:将函数作为参数或返回值的函数。
2、常见内置高阶函数:
三、lambda表达式:
四、闭包:
五、函数装饰器(decorators):
六、基础代码:
代码1:
"""
函数式编程 -- 方法作为参数
""" def fun01():
print("fun01执行喽") # 调用fun01,将返回值赋值给变量a
# a = fun01() # 将函数值赋值给变量a(没有执行fun01)
a = fun01
# 调用变量a,间接执行函数fun01
a() # 将方法fun01作为方法的参数func进行传递
def fun02(func):
print("fun02执行喽")
# 对于fun02的定义者而言,不知道也不需要知道func的具体逻辑.
func() fun02(fun01) list01 = [1,2,33,4,45,6]
# def find_demo01(target):
# for item in target:
# if item> 5:
# yield item
#
# def find_demo02(target):
# for item in target:
# if item % 2 != 0:
# yield item
#
# def find_demo03(target):
# for item in target:
# if item < 3:
# yield item # --------------------------------------------
# 相同点:
def find_demo(target,func):
for item in target:
# 本行代码,又将不变的与变化的紧密相连
# if condition01(item):
# 本行代码,使用形参func将不变的与变化的隔离开.
if func(item):
yield item
# --------------------------------------------
# 提取不同点:
def condition01(item):
return item> 5 def condition02(item):
return item % 2 != 0 def condition03(item):
return item < 3 for item in find_demo(list01,condition03):
print(item)
代码2:
"""
lambda 表达式(匿名方法)
语法:
lambda 参数:方法体
练习:
exercise05.py
""" def fun01():
print("我是普通方法") fun01() def fun02(a):
print("我是普通方法,参数是,", a) fun02(500) def fun03():
return True print(fun03()) # -------------------------
a01 = lambda: print("我是lambda方法")
a01() a02 = lambda a: print("我是lambda方法,参数是,", a)
a02(500) a03 = lambda: True
print(a03())
#------------------------------------ from common.custom_list_tools import ListHelper
list01 = [1,2,33,4,45,6] for item in ListHelper.find_all(list01,lambda item:item > 5):
print(item) for item in ListHelper.find_all(list01,lambda item:item % 2 != 0):
print(item) # 提取不同点:
# def condition01(item):
# return item> 5
#
# def condition02(item):
# return item % 2 != 0
#
# def condition03(item):
# return item < 3 # for item in ListHelper.find_all(list01,condition01):
# print(item)
代码3:
"""
高阶函数 """
from day16.common.custom_list_tools import ListHelper # 敌人类(编号/姓名/攻击力/血量/攻击速度...)
class Enemy:
def __init__(self, id, name, hp, atk, atk_speed):
self.id = id
self.name = name
self.hp = hp
self.atk = atk
self.atk_speed = atk_speed list01 = [
Enemy(101, "玄冥大老", 200, 800, 5),
Enemy(102, "玄冥小老", 150, 700, 3),
Enemy(103, "qtx", 800, 1000, 50),
Enemy(104, "吕泽玛利亚", 0, 300, 2),
Enemy(105, "赵金多", 500, 900, 10),
] # 1. filter 过滤,类似于ListHelper.find_all.
# 过滤出编号大于102的敌人
# for item in filter(lambda e: e.id > 102, list01):
# print(item.id)
#
# for item in ListHelper.find_all(list01, lambda e: e.id > 102):
# print(item.id) # 2. map 映射,类似于ListHelper.select
# 映射出所有敌人的姓名
for item in map(lambda e:e.name,list01):
print(item) for item in ListHelper.select(list01,lambda e:e.name):
print(item) # # 按照血量升序排列,类似于ListHelper.order_by
# for item in sorted(list01,key = lambda e:e.hp ):
# print(item.hp)
#
# # 按照血量降叙排列
# for item in sorted(list01,key = lambda e:e.hp,reverse=True):
# print(item.hp) # ListHelper.order_by(list01,lambda e:e.hp)
# for item in list01:
# print(item.hp) # 获取攻击力最大的敌人
result = max(list01,key = lambda e:e.atk)
print(result.name) result = ListHelper.get_max(list01,lambda e:e.atk)
print(result.name)
代码4:
"""
Encolsing 外部嵌套作用域
""" # 全局变量G
g01 = 100 def fun01():
# fun01局部变量L
# E外部嵌套作用域
a = 1 def fun02():
b = 2 # fun02局部变量L
# print("fun02:", a) # 可以访问外部嵌套变量a
# a = 2222 # 没有修改外部嵌套变量a,而是创建了新的局部变量a
# print("fun02:",a)
nonlocal a # 声明外部嵌套变量a
a = 2222
print("fun02:",a) fun02()
print("fun01:",a) fun01()
代码5:
"""
闭包 """ def fun01():
print("fun01执行喽")
a = 1
def fun02():
print("fun02执行喽")
print("外部变量是:",a)
return fun02 # 得到的是内部函数
result = fun01()
# 调用内部函数,因为内部函数使用了外部变量,所以称之为闭包.
result()# 可以使用外部变量,说明外部函数在调用后没有释放. # 案例: def give_gift_money(money):
"""
获取压岁钱
"""
print("得到了%d压岁钱"%money)
def child_buy(target,price):
"""
孩子需要买东西
"""
nonlocal money
if money >= price:
money -= price
print("孩子花了%d钱,买了%s,还剩下%d钱."%(price,target,money))
else:
print("压岁钱不够了")
return child_buy action = give_gift_money(10000)
action("98k",3500)
action("小猪佩奇",300)
action("大黄蜂",8000) # 体会:闭包使得逻辑连续(因为内部函数可以使用外部变量).
代码6:
"""
装饰器
-- 闭包的应用
""" # def say_hello():
# print("hello")
#
#
# def say_goodbye():
# print("goodbye")
#
#
# say_hello()
# say_goodbye() # 需求:在两个方法实现的功能基础上,增加新功能(打印方法名称) # def say_hello():
# print(say_hello.__name__)
# print("hello")
#
#
# def say_goodbye():
# print(say_goodbye.__name__)
# print("goodbye")
#
#
# say_hello()
# say_goodbye() # 缺点:代码重复.
# 解决:提取打印方法名称的功能 # def print_func_name(func):
# print(func.__name__)
#
# def say_hello():
# # print(say_hello.__name__)
# print_func_name(say_hello)
# print("hello")
#
#
# def say_goodbye():
# # print(say_goodbye.__name__)
# print_func_name(say_goodbye)
# print("goodbye") # say_hello()
# say_goodbye()
# 缺点:在两个已有功能的内部,增加新功能,代码可读性差. # def say_hello():
# # print_func_name(say_hello)
# print("hello") # def say_goodbye():
# # print_func_name(say_goodbye)
# print("goodbye")
#
# def print_func_name(func):
# # 包装新旧功能
# def wrapper():
# # 增加的新功能
# print(func.__name__)
# # 旧功能
# func()
#
# return wrapper # 返回包装器
#
# say_hello = print_func_name(say_hello)
# say_goodbye = print_func_name(say_goodbye)
#
# say_hello()
# say_goodbye() # 缺点:调用者完成包装新旧方法的任务.
# 解决:应该有定义者完成. # def print_func_name(func):
# # 包装新旧功能
# def wrapper():
# # 增加的新功能
# print(func.__name__)
# # 旧功能
# func()
#
# return wrapper # 返回包装器
#
# @print_func_name # say_hello = print_func_name(say_hello)
# def say_hello():
# print("hello")
# return "哈哈"
#
# @print_func_name
# def say_goodbye():
# print("goodbye")
#
# #---------以上是定义者--以下是调用者-----------------
# say_hello()
# say_goodbye() # 缺点:旧功能的返回值不能被客户端代码接受到.
# 旧功能的参数,客户端代码也无法传入. # def print_func_name(func):
# # 包装新旧功能
# def wrapper(name):
# # 增加的新功能
# print(func.__name__)
# # 旧功能
# return func(name)
#
# return wrapper # 返回包装器 # 缺点:包装器不能适应所有的旧功能参数
def print_func_name(func):
# 包装新旧功能
def wrapper(*args,**kwargs):
# 增加的新功能
print(func.__name__)
# 旧功能
return func(*args,**kwargs) return wrapper # 返回包装器 @print_func_name # say_hello = print_func_name(say_hello)
def say_hello(name):
print(name,"hello")
return "哈哈" @print_func_name
def say_goodbye(name,age):
print(age,name,"goodbye") #---------以上是定义者--以下是调用者-----------------
print(say_hello("张无忌"))
say_goodbye("赵敏",25)
代码7:
"""
练习:使用装饰器实现:
为两个已有功能(进入后台,删除订单),增加新功能(验证权限).
""" # 1. 定义装饰器(新功能 + 旧功能) def verify_permissions(func):
def wrapper(*args, **kwargs):
print("验证权限")
return func(*args, **kwargs)
return wrapper # 2. 拦截调用
@verify_permissions
def enter_background(loginId,pwd):
print(loginId,pwd)
print("进入后台系统.....") @verify_permissions
def delete_order(order_id):
print("删除%d订单..."%order_id) enter_background("zs",123)
delete_order(101)
代码8:
"""
练习2:为两个已有功能(存款取款),添加新功能(验证账户) """
def verify_accont(func):
def wrapper(*args,**kwargs):
print("验证账户")
return func(*args,**kwargs)
return wrapper #deposit = verify_accont(deposit)
@verify_accont
def deposit(money):
print("存款:",money) @verify_accont
def withdraw():
print("取钱")
return 10000 deposit(5000)
print(withdraw())
代码9:
"""
练习:
为学生的学习方法,添加新功能(打印执行时间)
""" import time def print_execute_time(func):
def wrapper(*args, **kwargs):
# 记录执行前的时间
start_time = time.time()
result = func(*args, **kwargs)
# 统计执行时间
execute_time = time.time() - start_time
print("执行时间是:", execute_time)
return result return wrapper class Student:
def __init__(self, name):
self.name = name @print_execute_time
def study(self):
print("开始学习喽")
time.sleep(2) # 睡眠两秒 模拟学习了两秒 s01 = Student("无忌")
s01.study()