python迭代器生成器
迭代器生成器区别
通俗版概念
迭代器(Iterator)
- 像“快递员送快递”:
你有一个包裹清单(比如Excel里的测试用例),快递员(迭代器)会按顺序一个一个送(遍历),直到送完。
✅ 适合场景:数据已经全部准备好(如从文件读取的测试用例列表)。
❌ 缺点:如果包裹太多(数据量大),一次性全放车上(内存)会塞不下。生成器(Generator)
- 像“现炒小菜”:
你去餐馆吃饭,厨师(生成器)不会提前炒好100盘菜,而是你点一盘(需要数据),他炒一盘(动态生成)。
✅ 适合场景:测试数据量极大(如1万用户注册)、分页接口遍历、大文件处理。
❌ 缺点:菜只能按顺序上(不能回头遍历)。
什么时候用迭代器?什么时候用生成器?
场景 用迭代器 用生成器 数据是否现成? 数据已经存在(如Excel、CSV文件) 数据需要动态生成(如参数化测试) 数据量大小 数据量小(比如100条用例) 数据量大(如1万用户、大文件) 是否需要省内存? 不需要(数据可一次性加载) 需要(数据分批生成或读取) 代码简洁性 直接遍历列表、字典 用 yield
一行搞定动态生成
一句话选择原则
- 用迭代器:数据现成的、量不大,直接遍历。
- 用生成器:数据量大、需要动态生成或省内存时(如测分页接口、大文件上传)。
场景1:遍历已有的测试用例(用迭代器)
需求:从CSV文件中读取100条测试用例,依次执行。
迭代器解决:直接遍历现成的数据集合。import unittest import csv import requests class TestAPI(unittest.TestCase): def test_all_cases(self): # 迭代器应用点1:csv.DictReader() 本身是一个迭代器 # 它会逐行读取CSV文件,而不是一次性加载全部数据到内存 with open("test_cases.csv", "r") as f: csv_reader = csv.DictReader(f) # <-- 这里创建了一个文件迭代器 # 迭代器应用点2:for循环本质是调用迭代器的__next__() # 每次循环读取一行数据(按需加载) for case in csv_reader: # <-- 这里隐式使用迭代器遍历 response = requests.request( case["method"], case["url"] ) self.assertEqual(response.status_code, 200, f"用例 {case} 请求失败")
迭代器在代码中的应用:
- **
csv.DictReader(f)
是迭代器**:
像「传送带」逐行传送CSV数据(不一次性堆内存),处理大文件不卡顿。- **
for case in csv_reader
**:
循环时自动触发「下一份!」动作(调用__next__()
),逐条拿数据测试。
场景说明(通俗版)
需求:用户注册接口需要测试各种随机用户名。
痛点:手动写100条用例太麻烦,一次性生成全部数据占内存。import unittest import requests # 生成器:生成100个用户(user_1到user_100) def user_generator(): for i in range(1, 101): # 改一个数字就能测任意次数 yield {"username": f"user_{i}", "email": f"user_{i}@test.com"} class TestUsers(unittest.TestCase): def test_100_users(self): for user in user_generator(): # 自动循环100次 response = requests.post("https://api.example.com/register", json=user) self.assertEqual(response.status_code, 200)
代码核心逻辑
生成器函数
user_generator()
:
range(1, 101)
→ 生成1到100的数字。yield
→ 每次循环吐出一个用户数据(如user_1
,user_2
...user_100
)。