# 手动实现一个自定义迭代器 # 我们可以通过定义一个类并实现__iter__()和__next__()方法来创建一个自定义的迭代器。 class MyCustomIterator: def __init__(self, data): self.data = data self.index = 0 def __iter__(self): return self def __next__(self): if self.index < len(self.data): result = self.data[self.index] self.index += 1 return result else: raise StopIteration my_inter_instance = MyCustomIterator([1, 2, 3]) for item in my_inter_instance: print(item) # 再次尝试遍历同一个迭代器实例,会发现它已经耗尽 print("\n--- 再次遍历已耗尽的自定义迭代器 ---") # 没有任何输出,此时my_inter_instance迭代器已耗尽 for item in my_inter_instance: print(item) # 迭代器 class MyCustomIterator: def __init__(self, data): self.data = data self.index = 0 def __iter__(self): return self def __next__(self): if self.index < len(self.data): result = self.data[self.index] self.index += 1 return result else: raise StopIteration # 可迭代对象 # Iterable 可迭代对象:实现了__iter__()方法,每次都都会返回一个新的Iterable 实例 class MyIterable: def __init__(self, data): self.data = data def __iter__(self): return MyCustomIterator(self.data) # 可以遍历多次 print("\n--- 可以遍历多次 ---") my_interbale = MyIterable([1, 2, 3]) # 第一次遍历 print("第一次遍历") for item in my_interbale: print(item) # 第二次遍历 print("第二次遍历") for item in my_interbale: print(item) # 验证每次iter()都会创建新的Iterator print("验证每次iter()都会创建新的Iterator") iterable = MyIterable([1, 2, 3]) it1 = iter(iterable) it2 = iter(iterable) print(f"两个Iterator是否是同一个对象{it1 is it2}") # False print(f"it1: {list(it1)}") print(f"it2: {list(it2)}") # Generator (生成器) # 5.1 概念与特点 # 生成器是Python中的一种特殊类型的迭代器,它允许你在迭代过程中逐渐生成值,而不是一次性生成所有的值。生成器由函数创建,这些函数使用yield关键字而不是return来返回值。 # 基本特点: # 惰性求值:只在需要时才生成值,节省内存 # 状态保持:函数在yield后暂停,保持内部状态 # 迭代器协议:遵循Python的迭代器协议 # 内存友好:特别适合处理大数据集 # 代码简洁:比手动实现迭代器更简洁 # 生成器函数 def simple_gen(): yield 1 yield 2 yield 3 gen = simple_gen() print(next(gen)) # 1 print(next(gen)) # 2 print(next(gen)) # 3 try: print(next(gen)) except StopIteration: print("生成器函数耗尽,没有更多值") def num_generator(): yield 1 yield 2 yield 3 yield 4 yield 5 gen = num_generator() # 通过for循环生成器,会自动调用next()进行执行 for num in gen: print(num) # yield关键字的工作原理 # yield是Python中用于创建生成器函数的一个关键字。与return语句类似,它也可以从函数返回值,但不同之处在于: # 当函数执行到yield语句时,它会暂停执行并将yield后的值返回给调用者 # 函数的状态(包括局部变量和指令指针)会被保存下来 # 在下次调用时从暂停的地方继续执行,而不是像return那样彻底退出函数 # 生成器表达式 # 除了生成器函数,Python还支持生成器表达式。它们与列表推导式(list comprehensions)语法类似,但使用圆括号()而不是方括号[],并且返回的是一个生成器对象,而不是一个完整的列表。 # 生成器在处理数据时具有显著的优势: # 内存效率高:生成器采用"惰性评估"(lazy evaluation)机制,不会立即将所有元素生成并存储在内存中,而是按需生成 # 处理大数据流:非常适合处理网络数据流、文件读取等场景,因为数据可以逐块处理 # 基本语法 print("生成器表达式") my_gen = (x**2 for x in range(5)) print(f"{type(my_gen)}") # for item in my_gen: print(item) # 高级特性 # 双向通信 (send()方法) # 生成器不仅可以向调用者返回值,还可以通过send()方法从调用者接收值。这使得生成器能够实现更复杂的协程(coroutine)行为。 # 定义一个支持双向通信的生成器函数 def double_yield(): # 第一个yield会暂停并等待外部send()发送值,将接收到的值赋给x # 注意:第一次启动生成器时,next()或send(None)会使这个yield接收None x = yield # 进入无限循环,持续进行双向通信 while True: # 暂停并返回x * 2的值,同时等待外部send()发送新的值给x x = yield x * 2 gen = double_yield() next(gen) # 启动生成器 print(gen.send(10)) print(gen.send(2)) # 异常处理 (throw()和close()方法) # 生成器提供了其他方法来控制其生命周期和行为: def exception_hanlding_generator(): try: while True: yield "正在运行中" except GeneratorExit: print("生成器关闭") finally: print("生成器清理完成") gen = exception_hanlding_generator() print(next(gen)) gen.close()