Python 如何使用 functools 模块

news2024/10/1 7:32:01

functools 模块是 Python 标准库中的一个重要模块,它提供了一些有用的高阶函数和工具,帮助开发者更轻松地操作和处理函数。functools 中的工具主要用于函数的缓存、包装、偏函数等功能。

1. functools 模块概述

functools 模块的设计目的是为了简化和增强函数操作。Python 是一种高度支持函数式编程的语言,而 functools 则进一步提供了一些函数式编程的便利工具,使得代码更易读、更易维护。

安装和导入

functools 是 Python 标准库的一部分,因此不需要额外安装,直接通过以下方式导入即可:

import functools

2. 偏函数(functools.partial

functools.partial 用于创建一个新的函数,该函数在调用时已经绑定了一些参数。偏函数的使用可以简化函数调用过程,特别是在一些参数固定的情况下。

使用示例:
from functools import partial

def power(base, exponent):
    return base ** exponent

# 创建一个新的函数,固定指数为2
square = partial(power, exponent=2)

# 调用时只需要传入底数
print(square(5))  # 输出 25

在上面的示例中,我们通过 partialpower 函数的 exponent 参数固定为 2,从而创建了一个新的 square 函数。这使得我们在调用 square 时,只需要提供底数即可,简化了函数调用的复杂度。

偏函数的优点:
  1. 提高代码复用性:通过固定某些参数,可以轻松创建新的函数,而不需要重复编写相似的代码。
  2. 简化函数接口:减少了函数的参数数量,使函数更易于使用。
  3. 增强代码可读性:偏函数通常有助于提高代码的可读性,因为它们明确了某些参数的固定值。

3. functools.wraps

functools.wraps 是一个装饰器,用于保存被装饰函数的元数据(如函数名称、文档字符串等),使得被装饰后的函数依然保留原始函数的特性。functools.wraps 通常与自定义装饰器一起使用。

使用示例:
from functools import wraps

def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print("Before function call")
        result = func(*args, **kwargs)
        print("After function call")
        return result
    return wrapper

@my_decorator
def say_hello(name):
    """This function says hello to the person passed in as the name."""
    return f"Hello, {name}!"

print(say_hello("Alice"))
print(say_hello.__name__)  # 输出 'say_hello'
print(say_hello.__doc__)   # 输出 'This function says hello to the person passed in as the name.'

在这个例子中,我们定义了一个装饰器 my_decorator,并使用 @wraps 来装饰内部的 wrapper 函数。@wraps 确保了 say_hello 函数在被装饰后,依然保留了原始函数的名称、文档字符串等信息。如果不使用 @wraps,这些信息可能会丢失,导致调试和文档生成变得更加困难。

4. 缓存(functools.lru_cache

functools.lru_cache 是一个非常强大的工具,用于缓存函数的返回结果,以加速重复计算。LRU 表示“最近最少使用”,该装饰器会缓存指定数量的最近调用结果,当缓存满了之后,会根据 LRU 策略丢弃最久未使用的缓存项。

使用示例:
from functools import lru_cache

@lru_cache(maxsize=128)
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

print(fibonacci(10))  # 输出 55

在这个例子中,fibonacci 函数使用了 @lru_cache 进行装饰。这样,当我们多次调用 fibonacci 时,对于相同的参数值,函数不会重复计算,而是直接从缓存中返回结果,从而大大提高了性能。

lru_cache 参数解释:
  • maxsize:缓存的最大数量。如果设置为 None,表示无限缓存。
  • typed:如果为 True,则将基于函数参数的类型进行缓存区分。例如 f(3)f(3.0) 将被视为不同的调用。
优点:
  1. 提升性能:通过缓存,减少了计算次数,尤其适用于递归或重复性高的函数。
  2. 简化代码:相比手动实现缓存机制,使用 lru_cache 更加简洁且易于维护。
注意事项:
  • 使用缓存可能会占用额外的内存,因此需要合理设置缓存的大小。
  • 对于副作用明显的函数(例如有 I/O 操作的函数),不适合使用 lru_cache,因为缓存可能会导致结果不一致。

5. functools.reduce

functools.reduce 是一个常用的高阶函数,它将一个二元函数(接受两个参数的函数)应用于序列的元素,将序列归约为单个值。reduce 常用于累积计算或聚合操作。

使用示例:
from functools import reduce

numbers = [1, 2, 3, 4, 5]
# 计算列表中所有数的乘积
product = reduce(lambda x, y: x * y, numbers)
print(product)  # 输出 120

在这个例子中,reducelambda x, y: x * y 这个二元函数依次应用于 numbers 列表的元素,最终得到所有元素的乘积。其计算过程如下:

  • 1 * 2 = 2
  • 2 * 3 = 6
  • 6 * 4 = 24
  • 24 * 5 = 120

最终结果为 120。

reduce 的工作原理:

reduce 从序列的第一个元素开始,依次将当前累计值与下一个元素应用于二元函数,直到处理完序列中的所有元素为止。

使用场景:

reduce 常用于需要将一系列值聚合为单个值的场景,如累加、求乘积、最大值计算等。

注意事项:
  • 虽然 reduce 功能强大,但在一些场景下,其使用可能会使代码难以理解。Python 3 中已经将 reduce 移出了内置函数,放到了 functools 模块中,这也是对其复杂性的一种提醒。

6. functools.total_ordering

functools.total_ordering 是一个类装饰器,它通过最少量的比较运算符定义,为类生成完整的比较方法集合。这对于需要实现比较运算符的类非常有用。

使用示例:
from functools import total_ordering

@total_ordering
class Student:
    def __init__(self, name, grade):
        self.name = name
        self.grade = grade

    def __eq__(self, other):
        return self.grade == other.grade

    def __lt__(self, other):
        return self.grade < other.grade

# 由于使用了 total_ordering,Student 类自动获得了其他比较运算符
alice = Student("Alice", 90)
bob = Student("Bob", 85)

print(alice > bob)  # 输出 True
print(alice <= bob)  # 输出 False

在这个例子中,我们只定义了 __eq____lt__ 两个比较方法,但 total_ordering 装饰器为我们自动生成了其他的比较运算符,如 __gt____le____ge__ 等等。

优点:
  1. 减少重复代码:只需定义部分比较方法,其他方法自动生成。
  2. 提高代码一致性:确保类的比较行为符合逻辑。
注意事项:
  • 要确保实现的比较方法是自洽的,以免生成的其他比较方法行为不一致。

7. functools.singledispatch

functools.singledispatch 是一个函数装饰器,它将一个通用函数(generic function)转换为一个单分派泛型函数。简单来说,它允许你根据第一个参数的类型对函数进行重载。

使用示例:
from functools import singledispatch

@singledispatch
def process(value):
    raise NotImplementedError("Unsupported type")

@process.register(int)
def _(value):
    return f"Processing integer: {value}"

@process.register(str)
def _(value):
    return f"Processing string: {value}"

@process.register(list)
def _(value):
    return f"Processing list: {', '.join(str(x) for x in value)}"

print(process(10))  # 输出 Processing integer: 10
print(process("Hello"))  # 输出 Processing string: Hello
print(process([1, 2, 3]))  # 输出 Processing list: 1, 2, 3

在这个例子中,我们使用 singledispatch 定义了一个通用函数 process,然后为不同类型的参数(intstrlist)分别注册了处理函数。singledispatch 根据传入参数的类型,自动调用相应的处理函数。

优点:
  1. 增强代码的扩展性:可以很方便地为新的类型添加处理函数,而无需修改已有代码。
  2. 保持代码整洁:避免了大量的 if-elif 判断语句。
注意事项:
  • 只能根据第一个参数的类型进行分派,这在某些情况下可能会限制函数的设计。

8. functools.cmp_to_key

functools.cmp_to_key 是一个实用工具,用于将旧式的比较函数(如 Python 2 中使用的 cmp 函数)转换为 key 函数,从而与 Python 3 的排序函数兼容。

使用示例:
from functools import cmp_to_key

# 定义一个旧式比较函数
def compare(a, b):
    return (a > b) - (a < b)

# 使用 cmp_to_key 将其转换为 key 函数
sorted_list = sorted([5, 2, 9, 1, 5, 6], key=cmp_to_key(compare))
print(sorted_list)  # 输出 [1, 2, 5, 5, 6, 9]

在这个例子中,compare 是一个旧式的比较函数,通过 cmp_to_key,我们可以将其转换为 key 函数,以便在 sorted 等函数中使用。

优点:
  1. 兼容性:允许旧式代码在 Python 3 中继续使用,而无需大规模重写。
  2. 简洁性:通过转换,简化了旧代码的适配工作。

functools 模块是 Python 函数式编程中的重要工具箱。通过 functools,可以更加简洁、高效地处理函数的包装、缓存、偏函数等操作。无论是提高代码的性能,还是增强代码的可读性,functools 都提供了丰富的工具和方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2065936.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

无人机+消防车:高楼灭火系统技术详解

“无人机消防车”高楼灭火系统技术是一种创新的消防解决方案&#xff0c;旨在解决高层建筑灭火难题。以下是对该技术的详细解析&#xff1a; 一、技术背景与需求 高层建筑数量多&#xff0c;火灾隐患多发。根据国家消防救援局发布的数据&#xff0c;高层建筑火灾频发&#xf…

MyBatis核心机制

实现MyBatis核心机制环境搭建 1.核心框架示意图 2.模块搭建 1.创建maven项目 2.引入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSc…

超维机器人在工业与能源领域的具身智能探索和应用

具身智能&#xff08;Embodied AI&#xff09;是指机器人能够通过其物理形态与环境的交互&#xff0c;进行感知、学习、决策和执行&#xff0c;从而完成复杂任务的能力。具身智能强调机器人不仅要具备感知环境和分析数据的能力&#xff0c;还要能够通过身体的行为和物理互动来适…

zabbix5.0与7.0版本区别 切换建议

Zabbix5.0和Zabbix7.0的区别 1. 性能和扩展性优化 1.1 高效的数据处理和存储 优化的数据库性能&#xff1a; Zabbix 7.0 在数据库层面进行了多项优化&#xff0c;以减少查询延迟和提高数据处理速度。这包括对数据库结构的改进和索引优化&#xff0c;使得大规模数据的读取和写…

Linux云计算 |【第二阶段】SECURITY-DAY3

主要内容&#xff1a; Prometheus监控服务器、Prometheus被监控端、Grafana监控可视化 补充&#xff1a;Zabbix监控软件不自带LNMP和DB数据库&#xff0c;需要自行手动安装配置&#xff1b;Prometheus监控软件自带WEB页面和DB数据库&#xff1b;Prometheus数据库为时序数据库&…

<数据集>翻越栏杆行为识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;512张 标注数量(xml文件个数)&#xff1a;512 标注数量(txt文件个数)&#xff1a;512 标注类别数&#xff1a;1 标注类别名称&#xff1a;[climbing] 使用标注工具&#xff1a;labelImg 标注规则&#xff1a;对类…

十五分钟两百行代码,手写一个vue项目全局通用的弹框

前言&#xff1a; 我们在写vue项目时&#xff0c;弹框是非常常用的组件&#xff0c;并且在同一个项目中&#xff0c;弹框大多类似。所以我们可以抽离封装出一个通用的弹框&#xff1b; 因为vue3可向下兼容&#xff0c;所以作者这边会使用vue2的写法&#xff0c;vue3写法大同小…

vue3 语法糖<script setup>

在 Vue 3 中&#xff0c;<script setup>是一种新的语法糖&#xff0c;它极大地简化了组件的编写方式。 <script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。当同时使用 SFC 与组合式 API 时该语法是默认推荐。 基本概念 简洁的语法&#xf…

使用Qg波形快速提取模型参数的新方法以准确捕获SiC MOSFET在不同负载条件下的开关特性

来源&#xff1a;Novel Methodology for Fast Model Parameter Extracting Using Qg Waveforms to Accurately Capture Switching Characteristics of SiC MOSFET Under Various Load Conditions&#xff08;ISPSD 24年&#xff09; 摘要 本文提出了一种快速提取模型参数的方…

类和对象(高级)

类和对象&#xff08;高级&#xff09; 一、运算符重载 运算符重载是对已有的运算符 指定新功能。不能创建新运算。 运算符重载关键字operator 思路&#xff1a; 1、弄懂运算符的运算对象的个数。&#xff08;个数决定了 重载函数的参数个数&#xff09; 2、识别运算符左边的…

【css】伪元素实现跟随鼠标移动的渐变效果

主要功能是在按钮上实现鼠标跟随渐变效果。每当用户将鼠标移动到按钮上时&#xff0c;按钮会显示一个以鼠标位置为中心的渐变效果。 1. 核心部分: 监听鼠标在元素内移动 监听鼠标在元素内移动&#xff0c;并触发该事件。 const handleMouseMove (e: MouseEvent) > {if (…

C#知识|语法拾遗:数据类型转换

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 其实关于数据转换在任何语言中都会涉及&#xff0c;无论是PLC编程语言&#xff0c;还是SCADA开发中的脚本语言&#xff0c;都会涉及&#xff0c;在前边学习JavaScript的内容时&#xff0c;也看过相关内容&#xff1a; …

[RAG]喂饭教程!Neo4J可视化GraphRAG索引

GraphRAG通过结合知识图谱&#xff0c;增加RAG的全局检索能力。今天我将讲解如何使用Neo4J可视化GraphRAG索引的结果&#xff0c;以便进一步的处理、分析&#xff0c;以小说提取的实体《仙逆》为例&#xff0c;一图胜千言。本文分为4小节&#xff0c;安装neo4j、导入GraphRAG索…

如何做服务端渲染?

node server 接收客户端请求&#xff0c;得到当前的请求url 路径&#xff0c;然后在已有的路由表内查找到对应的组件&#xff0c;拿到需要请求的数据&#xff0c;将数据作为 props、context或者store 形式传入组件 然后基于 react 内置的服务端渲染方法 renderToString()把组件…

vue一键打不同环境的包

1.配置package.json 主要看的是 "build:all": "vue-cli-service build && vue-cli-service build --mode test && vue-cli-service build --mode development", "scripts": {"dev": "vue-cli-service serve"…

【SpringBoot源码】SpringBoot监听机制分析

目录 一、简介 二、SpringBoot事件监听机制 1)加载ApplicationListener监听器实现类 2)获取运行监听器EventPublishingRunListener 3)发布事件 4)Spring事件发布multicastEvent() 一、简介 接下来我们分析下SpringBoot的事件监听机制的源码。 二、SpringBoot事件监…

Android系统安全 — 1-OpenSSL支持的常用加解密算法介绍

常用加解密算法介绍 1. 哈希算法 常见的函数包含MD系列、SHA-1、SHA-2家族、SHA-3家族、SM3等。 1.1 MD5&#xff08;单向散列算法&#xff09; 全称是Message-Digest Algorithm 5&#xff08;信息-摘要算法&#xff09;&#xff0c;经MD2、MD3和MD4发展而来。MD5算法的使用…

线索精细化管理实践:线上推广渠道线索管理的8个要点

在如今线索获取成本越来越高的情况下&#xff0c;如何获取增量线索、经营好存量线索、实现精细化、高效率线索管理对于企业来说至关重要。获取线索是一切行动的开始&#xff0c;与其建立起稳定、持续的信任关系&#xff0c;达成合作甚至引导复购&#xff0c;是整个线索管理链路…

泛微eteams OA对接金蝶云星空写入数据

需求&#xff1a; 公司需要先在OA上对准备生产的订单进行一次量产评审&#xff0c;所有相关人员评审通过后才可以进行生产&#xff0c;导致下工单的人员每次需要把OA上的信息复制到ERP进行审批。 为什么不直接在ERP上审批呢&#xff1f; 首先该节点涉及到很多不用ERP的用户&am…

盘点八月份最好用的五款报表制作工具,涵盖各功能,你都听说过吗?

一、报表制作软件的重要性 在现代企业运营中&#xff0c;数据的处理和分析是至关重要的。如何将复杂的数据信息以直观、易懂的方式展现出来&#xff0c;是提升决策效率和准确性的关键。因此报表制作软件成为企业必备的工具之一&#xff0c;它们通过图表化的方式&#xff0c;帮…