当前位置: 首页 > news >正文

Python基础④-装饰器、迭代器及常用函数篇

序言

本文聚焦于 Python 编程中的几个重要概念和工具,包括装饰器嵌套、迭代器、生成器、推导式以及常用内置函数。

这些知识点在数据处理、算法设计、性能优化等领域发挥着重要作用。

通过深入学习这些内容,我们可以让代码更加简洁、模块化,提高代码的可维护性和可读性,从而更好地应对复杂的编程需求。

1.装饰器嵌套

1.1 核心概念

装饰器能在不修改原函数代码的前提下,为函数添加额外功能(如日志、权限校验等 ),让代码更简洁、功能更易扩展。

一个函数可被多个装饰器依次装饰,执行时遵循特定顺序,像给函数层层包装,每层装饰器实现独立功能。

1.2 代码示例与执行流程

def wrapper1(fn):def inner():print('wrapper1 前置逻辑')fn()print('wrapper1 后置逻辑')return innerdef wrapper2(fn):def inner():print('wrapper2 前置逻辑')fn()print('wrapper2 后置逻辑')return inner@wrapper1
@wrapper2
def target():print('我是目标')target()
执行顺序解析如下:

在这里插入图片描述

这张图说明了运行的逻辑和规律,

同理,3,4个及以上的装饰器也是同样的道理。

记住一个规则就是:

装饰器嵌套时,加载顺序是从下往上(靠近函数的装饰器先装饰 ),执行顺序是从上往下(外层装饰器先触发 )。

在需要为函数叠加多个独立功能时,如同时加日志记录、性能统计、权限校验,用嵌套装饰器能清晰拆分功能,让代码模块化、易维护。

2. 迭代器(Iterator)

迭代器用于遍历可迭代对象(如列表、元组等 ),统一不同数据类型的遍历逻辑,让遍历操作更规范、灵活。

2.1 获取迭代器的方式

iter() 内置函数
对可迭代对象调用 iter() 可获取其迭代器。

lst = [1, 2, 3]
it = iter(lst)  # 获取列表的迭代器

在这里插入图片描述

__iter__() 特殊方法
可迭代对象内部实现了 __iter__() 方法,调用该方法也能获取迭代器(iter() 底层就是调用此方法 )。
示例(模拟可迭代对象逻辑 ):

class MyIterable:def __init__(self, data):self.data = datadef __iter__(self):return iter(self.data)
mi = MyIterable([4, 5, 6])
it = mi.__iter__()  # 等价于 iter(mi)

在这里插入图片描述

2.2 从迭代器中获取数据

next() 内置函数
调用 next() 可逐个获取迭代器中的数据,迭代到末尾再调用会抛出 StopIteration 异常。

lst = [1, 2, 3]
it = iter(lst)
print(next(it))  # 输出 1
print(next(it))  # 输出 2

在这里插入图片描述

__next__() 特殊方法
迭代器对象实现了 __next__() 方法,next() 函数底层调用该方法。

lst = [1, 2, 3]
it = iter(lst)
print(it.__next__())  # 输出 1,效果同 next(it)

在这里插入图片描述

2.3 迭代器与for循环的关系

for 循环本质是迭代器的语法糖,它会自动获取可迭代对象的迭代器,然后循环调用 next() 获取数据,直到捕获 StopIteration 异常结束循环。所以不可迭代的对象(未实现 __iter__() 等迭代协议 )无法用 for 循环遍历。

lst = [1, 2, 3]
# for 循环底层逻辑模拟
it = iter(lst)
while True:try:print(next(it))except StopIteration:break

在这里插入图片描述

这里的try跟except的意思是:我们在一个循环里尝试运行print(next(it))这个程序,当捕获到StopIteration异常时,while循环会通过break语句终止,从而结束迭代过程,但此时你程序循环外写的语句还是能够被正常执行。

2.4 迭代器的特性

迭代器自身也是可迭代的,同时具备以下特性:

2.4.1 单向遍历

迭代器只能从前往后逐个遍历数据,遍历过的元素无法再回退访问,就像读文件时的指针,只能单向移动。

it = iter([1, 2, 3])
print(next(it))  # 1,指针移动到下一个位置
print(next(it))  # 2,继续后移
# 无法再获取到 1
2.4.2 节省内存

迭代器按需生成数据,不会一次性把所有数据加载到内存,遍历大型数据集时优势明显。比如遍历一个包含百万级数据的生成器,迭代器每次只生成一个数据并返回,内存占用始终很低。

2.4.3 惰性机制

迭代器遵循惰性计算原则,在调用 next() 时才会生成并返回下一个数据,不调用则不执行任何计算,有效提升程序性能,避免不必要的资源消耗。

3. 生成器(Generator)

生成器本质就是迭代器,它简化了迭代器的创建过程,可以更便捷地实现自定义遍历逻辑,同时继承了迭代器的特性。

3.1 创建生成器的方式

3.1.1 生成器函数

函数体中包含 yield 关键字的函数就是生成器函数,调用它不会执行函数体代码,而是返回一个生成器对象。

def my_generator():yield 1yield 2yield 3
gen = my_generator()  # 返回生成器对象,不执行函数体
print(next(gen))  # 执行到第一个 yield,返回 1
print(next(gen))  # 执行到第二个 yield,返回 2

在这里插入图片描述

yield的作用就是,它是一种可返回数据,类似return,但yield不会终止函数执行,只是暂停并返回值。

此外,它支持分段执行函数内容,每次调用 next()(或 __next__() ),函数会从上次 yield 的位置继续执行到下一个 yield 处。

3.1.2 生成器表达式

语法:类似列表推导式,把方括号 [] 换成圆括号 ()

gen = (x * 2 for x in range(3))  # 创建生成器,按需生成数据
print(next(gen))  # 0 * 2 = 0
print(next(gen))  # 1 * 2 = 2

在这里插入图片描述

4. 推导式(Comprehension)

推导式用于简化数据结构(列表、集合、字典 )的创建过程,让代码更简洁、高效。

4.1 列表推导式

[数据 for 循环 if 判断],遍历可迭代对象,根据条件筛选并处理数据,生成新列表。

# 生成 0-4 每个数的平方组成的列表
square_lst = [x ** 2 for x in range(5)]  
print(square_lst)  # 输出 [0, 1, 4, 9, 16]# 筛选出 0-9 中的偶数并乘 2
even_lst = [x * 2 for x in range(10) if x % 2 == 0]  
print(even_lst)  # 输出 [0, 4, 8, 12, 16]

在这里插入图片描述

这个实际上等价于for循环遍历计算输出的,但这里列表推导式就能给你用一行程序实现这个功能。

4.2 集合推导式

{数据 for 循环 if 判断},逻辑与列表推导式类似,但生成的是集合(自动去重 )。

# 生成 0-4 每个数的平方组成的集合
square_set = {x ** 2 for x in range(5)}  
print(square_set)  # 输出 {0, 1, 4, 9, 16}(集合元素无序)# 筛选出字符串中不重复的字母(忽略大小写 )
s = "Hello World"
unique_chars = {c.lower() for c in s if c.isalpha()}  
print(unique_chars)  # 输出 {'h', 'e', 'l', 'o', 'w', 'r', 'd'}

在这里插入图片描述

4.3 字典推导式

{k: v for 循环 if 判断},用于创建字典,k 是键,v 是对应的值。

# 生成键为 0-4,值为对应键平方的字典
square_dict = {x: x ** 2 for x in range(5)}  
print(square_dict)  # 输出 {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}# 交换字典的键和值(原字典值需可哈希 )
original_dict = {'a': 1, 'b': 2}
reversed_dict = {v: k for k, v in original_dict.items()}  
print(reversed_dict)  # 输出 {1: 'a', 2: 'b'}

在这里插入图片描述

这里可以看到推导式虽简洁,但复杂逻辑下很容易降低代码可读性,还是得合理使用。

5. 常用内置函数

5.1 zip函数

这个函数将多个可迭代对象(如列表、元组 )中对应位置的元素打包成元组,返回一个迭代器,长度以最短的可迭代对象为准。

lst1 = [1, 2, 3]
lst2 = ['a', 'b', 'c']
zipped = zip(lst1, lst2)  # 返回迭代器
# 转换为列表查看内容
print(list(zipped))  # 输出 [(1, 'a'), (2, 'b'), (3, 'c')]

在这里插入图片描述

同时遍历多个可迭代对象,配对处理对应元素,比如还可以通过以下程序将两个列表的元素一一关联成字典。

keys = ['a', 'b', 'c']
values = [1, 2, 3]
new_dict = {k: v for k, v in zip(keys, values)}
print(new_dict)  # 输出 {'a': 1, 'b': 2, 'c': 3}

在这里插入图片描述

5.2 sorted函数

对可迭代对象进行排序,返回一个新的排序列表,默认升序,可通过 key 参数自定义排序规则,reverse 参数控制升序/降序。

lst = [3, 1, 2]
# 默认升序排序
sorted_lst = sorted(lst)  
print(sorted_lst)  # 输出 [1, 2, 3]# 降序排序
sorted_lst_desc = sorted(lst, reverse=True)  
print(sorted_lst_desc)  # 输出 [3, 1, 2]# 按字符串长度排序(对列表里的字符串排序 )
str_lst = ['apple', 'banana', 'cherry']
sorted_by_len = sorted(str_lst, key=len)  
print(sorted_by_len)  # 输出 ['apple', 'cherry', 'banana']

在这里插入图片描述

5.3 filter函数

根据条件筛选可迭代对象中的元素,返回一个迭代器。接收两个参数,第一个是判断函数(返回布尔值 ),第二个是可迭代对象。

def is_even(x):return x % 2 == 0
lst = [1, 2, 3, 4]
filtered = filter(is_even, lst)
# 转换为列表查看结果
print(list(filtered))  # 输出 [2, 4]

在这里插入图片描述

filtermap 返回的都是迭代器(生成器的一种 ),如需查看完整结果或进行多次遍历,可通过 list() 转换为列表,但要注意内存消耗,大型数据场景下按需使用。

通过学习迭代器、生成器、推导式及这些内置函数,能更高效地处理 Python 中的数据遍历、创建和转换任务。

小结

本学习笔记从装饰器、迭代器、生成器以及常用内置函数这几个方面进行讲解说明,希望对读者有帮助。

http://www.lryc.cn/news/592697.html

相关文章:

  • [Linux]如何設置靜態IP位址?
  • setTimeout、setInterval、requestAnimationFrame的使用以及区别
  • LeetCode1047删除字符串中的所有相邻重复项
  • Kubernetes Pod深度理解
  • 20250718-6-Kubernetes 调度-Pod对象:环境变量,初始容器,静态_笔记
  • LLM(Large Language Model)大规模语言模型浅析
  • 【c++】中也有floor函数吗?他与JavaScript中的floor有啥区别?
  • RPC 与 Feign 的区别笔记
  • Nestjs框架: 基于TypeORM的多租户功能集成
  • Java全栈面试实录:从Spring Boot到AI大模型的深度解析
  • 北斗网格位置码详解:经纬度到二维网格码的转换(非极地)
  • 智能点餐推荐网站,解决选择困难
  • Honeywell霍尼韦尔DV-10 变速器放大器 输入 15-28 VDC,输出 +/- 10VDC 060-6881-02
  • 数字化转型:概念性名词浅谈(第三十讲)
  • GaussDB join 连接的用法
  • 工业互联网六大安全挑战的密码“解法”
  • 聊聊 RocketMQ 4.X 知识体系
  • 【Linux】基本指令(入门篇)(上)
  • 人工智能day9——模块化编程概念(模块、包、导入)及常见系统模块总结和第三方模块管理
  • Docker部署前后端分离项目——多项目共享环境部署
  • Android sdk 升级 34到35
  • 计算机“十万个为什么”之跨域
  • c语言笔记---结构体
  • 一个简单的带TTL的LRU的C++实现
  • windows终端美化(原生配置+Oh My Posh主题美化)
  • 数据交易“命门”:删除权与收益分配的暗战漩涡
  • 《通信原理》学习笔记——第四章
  • LP-MSPM0G3507学习--05中断及管脚中断
  • 【DPDK】高性能网络测试工具Testpmd命令行使用指南
  • ELK结合机器学习模型预测