015 函数式编程

文章目录

    • 函数式编程
    • 函数式编程思想
    • 静态方法
    • 可迭代对象工具集
    • 函数作为参数
      • lambda 匿名方法
      • 内置高阶函数
    • Enclosing 外部嵌套作用域:函数嵌套
    • 函数作为返回值
      • 闭包
      • 装饰器
        • 装饰器代码
        • 推导过程

函数式编程

定义:用一系列函数解决问题
–函数可以赋值给变量,赋值后变量绑定函数
–允许将函数作为参数传入另一个函数
–允许函数返回一个函数
高阶函数:
将函数作为参数或返回值的函数

函数式编程思想

    适用性:
        多个函数,主体逻辑相同,但核心算法不同.
    步骤:
        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]

函数作为参数

lambda 匿名方法

注意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 )


Enclosing 外部嵌套作用域:函数嵌套

"""
    外部嵌套作用域 :函数嵌套。
"""

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)

你可能感兴趣的:(python,python,开发语言,函数式编程)