当前位置: 首页 > 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.dtcms.com/a/286584.html

相关文章:

  • 在断网情况下,网线直接连接 Windows 笔记本和 Ubuntu 服务器进行数据传输
  • 高性能数据库-Redis详解
  • verilog tb文件 美化terminal输出
  • Webpack 项目构建优化详解
  • 雪豹大模型驱动效率革命 华鼎冷链科技重构餐饮供应链神经网络
  • 进程 线程 并发 并行
  • 安达发|从救火到未雨绸缪:APS生产计划排产软件重塑制造业“危机免疫力“
  • 2025年6月电子学会全国青少年软件编程等级考试(Python一级)真题及答案
  • 添加DNS解析记录时,提醒记录冲突是怎么回事?
  • Python练习2-格式化输出基本数据类型及变量的详细使用
  • Aqara 携手西门子西碳迹SiTANJI,发布亚马逊 CPF 绿标解决方案标杆案例
  • 根据用户id自动切换表查询
  • c语言笔记---结构体
  • 浏览器元素定位工具-项目源码免费领取
  • 萤石摄像头C++SDK应用实例
  • 前端笔记之 async/await 异步编程详解
  • 面试高频题 力扣 695.岛屿的最大面积 洪水灌溉(FloodFill) 深度优先遍历 暴力搜索 C++解题思路 每日一题
  • Python网络爬虫之selenium库
  • 第九章 基础设施更新工程
  • 语音控制操作板:人机交互的未来趋势
  • 企业级异常处理方案:Spring Boot自定义异常全局拦截实战
  • 多线程的认识
  • 深入Java注解:从内置到元注解与自定义实战指南
  • 变量提升知识总结
  • 前后端数据交互,关于表单数据传输问题
  • 图机器学习(11)——链接预测
  • Linux和git常用命令
  • TF-IDF(Term Frequency - Inverse Document Frequency)
  • RFID技术赋能智慧物流:实现搬运环节的精准化与高效化
  • 【PTA数据结构 | C语言版】多叉堆的上下调整