Python迭代器与生成器:高效数据处理指南

一、迭代器(Iterators)

1. 定义与用途

  • 迭代器 :实现了 __iter____next__ 方法的对象,用于逐个访问集合中的元素。

  • 特点

    • 惰性计算:按需生成元素,节省内存。

    • 只能单向遍历,遍历结束后抛出 StopIteration 异常。

python 复制代码
class Counter:
    def __init__(self, start, end):
        self.current = start
        self.end = end

    def __iter__(self):
        return self

    def __next__(self):
        if self.current > self.end:
            raise StopIteration
        else:
            self.current += 1
            return self.current - 1

# 使用迭代器
counter = Counter(1, 3)
for num in counter:
    print(num)  # 输出:1 2 3

二、生成器(Generators)

1. 定义与用途

  • 生成器 :一种特殊的迭代器,使用 yield 关键字简化迭代器的创建。

  • 特点

    • 自动实现 __iter____next__

    • 状态挂起:每次 yield 后暂停,下次调用恢复执行。

2. 语法示例

(1) 生成器函数
python 复制代码
def count_generator(start, end):
    current = start
    while current <= end:
        yield current
        current += 1

gen = count_generator(1, 3)
for num in gen:
    print(num)  # 输出:1 2 3
(2) 生成器表达式
python 复制代码
squares = (x**2 for x in range(5))
print(list(squares))  # 输出:[0, 1, 4, 9, 16]

三、装饰器(Decorators)

1. 定义与用途

  • 装饰器:一种高阶函数,用于修改或增强其他函数的行为(如日志、权限校验)。

  • 本质 :接受函数作为参数,返回新函数的语法糖(使用 @ 符号)。

2. 语法示例

(1) 基础装饰器
python 复制代码
def logger(func):
    def wrapper(*args, **kwargs):
        print(f"调用函数:{func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@logger
def add(a, b):
    return a + b

print(add(2, 3))  # 输出:调用函数:add → 5
(2) 保留元信息(使用 functools.wraps
python 复制代码
from functools import wraps

def timer(func):
    @wraps(func)  # 保留原函数的元信息
    def wrapper(*args, **kwargs):
        import time
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} 执行耗时:{end - start:.2f}秒")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(1)

slow_function()

四、上下文管理器(Context Managers)

1. 定义与用途

  • 上下文管理器 :通过 with 语句管理资源(如文件、锁),确保资源的正确获取和释放。

  • 核心方法__enter__(进入上下文)和 __exit__(退出上下文)。

2. 语法示例

(1) 基于类的实现
python 复制代码
class FileManager:
    def __init__(self, filename, mode):
        self.filename = filename
        self.mode = mode

    def __enter__(self):
        self.file = open(self.filename, self.mode)
        return self.file

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.file.close()

with FileManager("test.txt", "w") as f:
    f.write("Hello, Context Manager!")
(2) 使用 contextlib 生成器简化
python 复制代码
from contextlib import contextmanager

@contextmanager
def file_manager(filename, mode):
    try:
        f = open(filename, mode)
        yield f
    finally:
        f.close()

with file_manager("test.txt", "w") as f:
    f.write("Hello, contextlib!")

五、元类(Metaclasses)

1. 定义与用途

  • 元类:类的类,用于控制类的创建行为(如自动添加方法、验证属性)。

  • 默认元类type(所有类的元类)。

  • 适用场景:框架开发、ORM(如 Django 模型)。

2. 语法示例

(1) 自定义元类
python 复制代码
class Meta(type):
    def __new__(cls, name, bases, attrs):
        # 强制类必须包含 `author` 属性
        if "author" not in attrs:
            raise TypeError("类必须定义 author 属性")
        return super().__new__(cls, name, bases, attrs)

class Book(metaclass=Meta):
    author = "Anonymous"  # 若无此行,定义时报错

# 使用元类控制类的创建

(2) 动态创建类

python 复制代码
# 使用 type 创建类
MyClass = type("MyClass", (), {"x": 10})
obj = MyClass()
print(obj.x)  # 输出:10

六、对比总结

概念 核心用途 关键语法 适用场景
迭代器 按需遍历集合元素 __iter__, __next__ 大数据集处理
生成器 简化迭代器实现,惰性计算 yield 流式数据处理、协程
装饰器 增强或修改函数行为 @decorator 日志、权限、缓存
上下文管理器 安全管理资源(自动释放) with + __enter__/__exit__ 文件、网络连接、锁
元类 控制类的创建行为 metaclass=Meta 框架开发、类级别约束

七、最佳实践

  1. 优先使用生成器:简化迭代器代码,减少内存占用。

  2. 装饰器保持简洁 :避免过度嵌套,用 functools.wraps 保留元信息。

  3. 上下文管理器管理资源 :替代 try...finally,提高代码可读性。

  4. 谨慎使用元类:仅在必要时使用(大多数场景可通过继承或装饰器替代)。


八、综合示例

生成器 + 装饰器 + 上下文管理器

python 复制代码
from contextlib import contextmanager
from functools import wraps

# 装饰器:记录函数执行时间
def timer(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        import time
        start = time.time()
        result = func(*args, **kwargs)
        print(f"{func.__name__} 耗时 {time.time() - start:.2f}秒")
        return result
    return wrapper

# 上下文管理器:文件操作
@contextmanager
def open_file(filename, mode):
    try:
        f = open(filename, mode)
        yield f
    finally:
        f.close()

# 生成器:逐行读取大文件
@timer
def read_large_file(filename):
    with open_file(filename, "r") as f:
        for line in f:
            yield line.strip()

# 使用
for line in read_large_file("big_data.txt"):
    print(line)
相关推荐
roman_日积跬步-终至千里22 分钟前
【Go语言基础【3】】变量、常量、值类型与引用类型
开发语言·算法·golang
roman_日积跬步-终至千里30 分钟前
【Go语言基础】基本语法
开发语言·golang·xcode
Felven41 分钟前
C. Basketball Exercise
c语言·开发语言
烛阴1 小时前
Python枚举类Enum超详细入门与进阶全攻略
前端·python
海棠蚀omo1 小时前
C++笔记-C++11(一)
开发语言·c++·笔记
Y第五个季节1 小时前
docker-部署Nginx以及Tomcat
java·开发语言
小道士写程序2 小时前
Qt 5.12 上读取 .xlsx 文件(Windows 平台)
开发语言·windows·qt
ou.cs2 小时前
c# :this() 和 :base()区别
开发语言·c#
Mikhail_G2 小时前
Python应用函数调用(二)
大数据·运维·开发语言·python·数据分析
weixin_472339462 小时前
使用Python提取PDF元数据的完整指南
java·python·pdf