Python高级编程:Functools模块的8个高级用法,强烈建议添加到你的开发工具箱中!

本文主要是介绍Python高级编程:Functools模块的8个高级用法,强烈建议添加到你的开发工具箱中!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1. functools.partial

2. functools.lru_cache

lru_cache的特点

cache的特点

性能比较与选择

3. functools.reduce

functools.reduce的作用

工作原理

示例

累加序列中的所有元素

计算阶乘

initializer的使用

应用场景

示例:计算平均销售额

小结

4. functools.update_wrapper

应用场景

5. functools.wraps

灵活性和自定义控制

低级控制和组合

理解装饰器实现细节

小结

6. functools.total_ordering

functools.total_ordering的作用

原理与实现

应用场景

小结

7. functools.singledispatch

functools.singledispatch的作用

原理与实现

应用场景

使用singledispatchmethod装饰类方法

小结

8. functools.cached_property (Python 3.8+)

functools.cached_property的作用

functools.cached_property的实现原理

详细示例

应用场景

注意事项

小结

结论



Python 是一门多功能语言,其众多优点之一就是它有很多功能强大的内置模块,这些模块使我们程序员在很多时候不用重复造轮子。functools 模块就是这样一个典型的例子。充分利用它可以让我们的 Python 代码更整洁、清晰和专业。

本文将介绍 Python 这个杰出模块的 8 个必知用途。阅读后,相信你能够在“Python 大师”的路上更进一步。

1. functools.partial

创建一个函数的新版本,并固定部分参数,减少重复传递参数的次数。类似于方法重写。

Python 有很多易用的内置函数,但是有时候对于特殊的案例我们必须向它们添加特定的参数。比如,int() 函数可以用于将字符串转换为整数。如果待转换的字符串是一个二进制整数的话,我们必须添加第二个参数:

print(f"The binary integer 101101 is equal: {int('101101', base=2)}")
# The binary integer 101101 is equal: 45

如果我们需要频繁地使用这个二进制转换功能,却总是重复写入相同的第二个参数,那将是很烦人的(同时看起来也是蠢蠢的)。

那么有没有一种方法可以让我们一处实现多处使用呢?functools 中的 partial 方法刚好可以帮助我们达到这个目的,让我们的代码变得更简洁:

from functools import partialbinary_trans = partial(int, base=2)
print(f"101101 (base 2) is equal to: {binary_trans('101101')} (base 10)")
print(f"1111110 (base 2) is equal to: {binary_trans('1111110')} (base 10)")
print(f"11111111 (base 2) is equal to: {binary_trans('11111111')} (base 10)")

输出结果如下:

101101 (base 2) is equal to: 45 (base 10)
1111110 (base 2) is equal to: 126 (base 10)
11111111 (base 2) is equal to: 255 (base 10)

这样一来,不管后续调用多少次,我们都不必给出第二个参数,实现定制化转换功能。当然,对于自定义函数,也同样可以使用 partial 方法。

from functools import partialdef multiply(x, y):
    return x * ydouble = partial(multiply, 2)
print(double(5))  # 输出 10

这里的 partial 实现了某个数值 2 倍的定制化计算功能。

2. functools.lru_cache

使用最近最少使用(Least Recently Used, LRU)缓存装饰器,提高函数的性能,尤其适用于计算密集型或 I/O 密集型函数。

下面看一个常见的例子,即斐波那契数列数字的计算,我们分别用常规方法和缓存方法实现,看看它们之间的性能差距:

from functools import lru_cache
import timeitdef fibonacci_norm(n):if n < 2:return nreturn fibonacci_norm(n - 1) + fibonacci_norm(n - 2)@lru_cache(maxsize=32)
def fibonacci_lru_cached(n):if n < 2:return nreturn fibonacci_lru_cached(n - 1) + fibonacci_lru_cached(n - 2)def timed_fibonacci_norm():resutl = fibonacci_norm(30)return resutldef timed_fibonacci_cached():resutl = fibonacci_lru_cached(30)# 清除缓存结果fibonacci_lru_cached.cache_clear()return resutlif __name__ == '__main__':time_norm = timeit.timeit(timed_fibonacci_norm, number=50)time_cached = timeit.timeit(timed_fibonacci_cached, number=50)print(f'Average time for fibonacci (norm): {time_norm / 50} s')print(f'Average time for fibonacci (cached): {time_cached / 50} s')print(f'Cached version is faster than norm: {time_norm / time_cached / 50}')

执行结果如下:

Average time for fibonacci (norm): 0.1954923020000024 s
Average time for fibonacci (cached): 1.077199999599543e-05 s
Cached version is faster than norm: 362.9637988724064

从上面的结果可以看出,相较于常规方法,使用 lru_cache 方法速度快了大约 363 倍,对性能的提升非常显著。而且随着计算数字的增大,这个差距还会继续扩大。

此外,缓存方法还有另一种实现方式,即 cache 装饰器。其实现方式与 lru_cache 类似。我们可以看看它与常规方法的性能差距:

from functools import cache
import timeit@cache
def fibonacci_cached(n):
    if n < 2:
        return n
    return fibonacci_cached(n - 1) + fibonacci_cached(n - 2)def timed_fibonacci_cached():
    resutl = fibonacci_lru_cached(30)
    # 重新装饰函数以清楚缓存
    fibonacci_cached = cache(fibonacci_lru_cached)
    return resutl
    
if __name__ == '__main__':
    time_norm = timeit.timeit(timed_fibonacci_norm, number=50)
    time_cached = timeit.timeit(timed_fibonacci_cached, number=50)
    print(f'Average time for fibonacci (norm): {time_norm / 50} s')
    print(f'Average time for fibonacci (cached): {time_cached / 50} s')
    print(f'Cached version is faster than norm: {time_norm / time_cached / 50}')

可以看出,cache 的性能更好,比常规方法快了约 1213 倍,主要是因为 lru_cache 存在缓存策略,所以在缓存管理上会有一定开销。

lru_cache 和 cache 各有其优点和适用场景,性能上的差异主要取决于具体的使用场景和缓存策略的需求。下面是一些对比和选择建议:

lru_cache的特点

  • LRU 缓存策略lru_cache 使用最近最少使用(Least Recently Used, LRU)策略,当缓存达到最大容量时,会自动清除最久未使用的条目。这对于需要限制缓存大小并且期望自动管理缓存淘汰的场景非常有用。

  • 缓存统计信息lru_cache 提供缓存命中率等统计信息(通过 cache_info 方法),有助于监控和优化缓存使用。

  • 性能:在缓存大小有限且需要频繁访问缓存条目的情况下,lru_cache 能够显著提升性能,但在缓存管理上会有一定的开销。

cache的特点

  • 无缓存策略cache 是一个简单的无策略缓存,它没有缓存淘汰机制,即缓存条目会一直保留,直到程序终止或显式清除。这适合于需要缓存所有结果且不需要考虑内存限制的场景。

  • 性能cache 的性能开销较小,因为它没有管理缓存条目的开销,在没有内存限制和缓存淘汰需求的情况下,cache 可以提供更好的性能。

性能比较与选择

  • 内存限制:如果你的应用需要限制内存使用,并且缓存数据量可能很大,选择 lru_cache 更为合适,因为它能够自动管理缓存大小并清除旧条目。

  • 缓存条目数量少:如果缓存的数据量较少,且不会超出内存限制,使用 cache 会更加简单高效,因为它没有缓存管理的开销。

  • 缓存管理需求:如果你需要了解缓存的使用情况和命中率,lru_cache 提供的统计信息会很有帮助。

  • 性能测试:对于特定应用场景,可以通过实际测试来比较两者的性能。可以使用 timeit 模块进行多次调用的时间测量,评估两者在实际应用中的表现。

3. functools.reduce

functools.reduce 是 Python 很重要的高阶函数之一,它用于对可迭代对象中的元素进行累计操作,最终将其简化为单一的值。reduce 可以说是一个“归约”函数,通过对序列中的元素依次应用指定的二元操作,将序列归约为一个值。

functools.reduce的作用

reduce 的作用是对序列进行二元操作,并将序列简化为一个单一的值。它的使用格式如下:

from functools import reduceresult = reduce(function, iterable[, initializer])
  • function:一个接受两个参数的函数,reduce 会将其应用于 iterable 的元素。

  • iterable:一个可迭代对象(如列表、元组等)。

  • initializer(可选):初始值,如果提供,则首先将其与序列的第一个元素一起传递给

这篇关于Python高级编程:Functools模块的8个高级用法,强烈建议添加到你的开发工具箱中!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1066552

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss