本文共 4498 字,大约阅读时间需要 14 分钟。
迭代器是一种对象,实现了Python的迭代协议(__iter__() 和 __next__() 方法)。通过迭代器,可以逐个访问容器中的元素。
__iter__():返回自身。__next__():返回下一个元素;如果没有更多元素,则抛出 StopIteration 异常。__iter__() 方法,返回一个迭代器。__iter__() 又实现 __next__()。代码如下(示例):
arr = [1, 2, 3, 4, 5]iterator = iter(arr)# 通过多次调用 next() 获取元素re = next(iterator)print(re) # 输出: 1re = next(iterator)print(re) # 输出: 2# 迭代器用完后再次调用 next() 会抛出 StopIteration# try:# re = next(iterator)# except StopIteration:# print("迭代器用完") 12345
代码如下:
class Box: def __init__(self, width): self.width = width def __iter__(self): return self def __next__(self): if self.width > 0: self.width -= 1 return self.width else: raise StopIterationb1 = Box(6)for i in b1: print(i)
6 5 4 3 2 1
代码如下:
import mathclass myData: def __init__(self, data, batch_size=10): self.data = data self.index = -1 self.batch_size = batch_size def __iter__(self): return self def __next__(self): self.index += 1 if self.index >= math.ceil(len(self.data) / self.batch_size): raise StopIteration return self.data[self.index * self.batch_size : self.index * self.batch_size + self.batch_size]data = myData( ["a", "b", "c", "d", "asd", "asd", "asdf", "12as", "asasd", "a", "b", "c", "d", "asd", "asd", "asdf", "12as", "asasd"], batch_size=4)data_loader = iter(data)# 获取前几批数据re = next(data_loader)print(re) # 输出: ['a', 'b', 'c', 'd']re = next(data_loader)print(re) # 输出: ['asd', 'asd', 'asdf', '12as']re = next(data_loader)print(re) # 输出: ['asasda', 'b', 'c', 'd']re = next(data_loader)print(re) # 输出: ['asd', 'asd', 'asdf', '12as']re = next(data_loader)print(re) # 输出: 'asasd'
['a', 'b', 'c', 'd']['asd', 'asd', 'asdf', '12as']['asasda', 'b', 'c', 'd']['asd', 'asd', 'asdf', '12as']['asasd']
生成器是一种特殊的迭代器,通过函数定义,用 yield 关键字生成值。生成器可以自动实现迭代协议,无需手动实现 __iter__() 和 __next__() 方法。
next() 时生成一个值。代码如下:
def fn(): print("111") yield "10000" print("222") yield "20000"re = fn()print(1) # 输出: 1print(next(re), "=============") # 输出: 10000 =============print(2) # 输出: 2print(next(re)) # 输出: 20000 =============print(3) # 输出: 3 11110000 =============2222200003
代码如下:
def fibonacci(n): a, b = 0, 1 for _ in range(n): yield b a, b = b, a + bfib_gen = fibonacci(10)for num in fib_gen: print(num)
11235813213455
| 特性 | 迭代器 | 生成器 |
|---|---|---|
| 实现 | 手动实现类方法 | 使用函数和 yield 定义 |
| 代码简洁性 | 较复杂 | 简单 |
| 状态管理 | 手动管理 | 自动保存 |
| 惰性计算 | 支持 | 支持 |
| 示例应用 | 复杂迭代逻辑 | 简单数据流生成 |
程序可能出错时,后面的代码不执行。为了让程序继续执行,可以使用异常处理语法。异常处理可以让程序在出错后继续执行后面的代码,增强程序的健壮性。
except 子句可以有 1 个或多个错误类型匹配。else 子句在没有错误发生时执行。finally 子句在任何情况下都执行。代码如下:
try: arr = [100, 20] x = arr[100] # 出错 print(x)except IndexError: print("数组越界")except ValueError: print("数据类型错误")else: print("没有异常")finally: print("不管有没有异常,都会执行")# 输出:# 数组越界# 不管有没有异常,都会执行 def fn(): x = 10 if 5 < x: print(x) else: raise ValueError("x的值不在范围内")try: fn()except ValueError as e: print(e)print("后续代码") 以下是几种常见的错误类型及其说明:
| 错误类型 | 说明 |
|---|---|
| ZeroDivisionError | 除法或取模运算中除以零 |
| ValueError | 传入无效的参数 |
| AssertionError | 断言语句失败 |
| StopIteration | 迭代器没有更多值 |
| IndexError | 序列中没有对应的索引 |
| IndentationError | 缩进错误 |
| OSError | 输入/输出操作失败 |
| ImportError | 导入模块失败 |
| NameError | 未声明/初始化对象 |
| AttributeError | 对象没有属性 |
| GeneratorExit | 生成器(generator) 被异常退出 |
| TypeError | 对类型无效的操作 |
| KeyboardInterrupt | 用户中断执行(通常是输入^C) |
| OverflowError | 数值运算超出最大限制 |
| FloatingPointError | 浮点计算错误 |
| BaseException | 所有异常的基类 |
| SystemExit | 解释器请求退出 |
| Exception | 常规错误的基类 |
| StandardError | 所有内建标准异常的基类 |
| ArithmeticError | 所有数值计算错误的基类 |
| EOFError | 到达输入末尾(EOF) |
| EnvironmentError | 操作系统错误的基类 |
| WindowsError | 系统调用失败 |
| LookupError | 无效数据查询的基类 |
| KeyError | 映射中没有对应的键 |
| MemoryError | 内存溢出错误 |
| UnboundLocalError | 访问未初始化的本地变量 |
| ReferenceError | 弱引用(Weak reference) 访问已经垃圾回收了的对象 |
| RuntimeError | 一般的运行时错误 |
| NotImplementedError | 尚未实现的方法 |
| SyntaxError | 语法错误 |
| TabError | 代码中混合了 tab 和 空格 |
| SystemError | 一般解释器系统错误 |
| UnicodeError | Unicode 相关错误 |
| UnicodeDecodeError | Unicode 解码时的错误 |
| UnicodeEncodeError | Unicode 编码时错误 |
| UnicodeTranslateError | Unicode 转换时错误 |
def get_age(): age = int(input("请输入年龄:")) if age > 140 or age < 1: raise ValueError("年龄超出范围!") else: print("年龄:", age)get_age() ValueError: 年龄超出范围!
转载地址:http://ooofk.baihongyu.com/