如何获取yield返回的索引?解决生成器不可下标访问错误
解决生成器无法下标访问的TypeError问题
这个错误的根源很明确:你调用iter_commit(strSiteMap)[0]和[1]时,试图把生成器对象当成列表/序列来取下标,但生成器是迭代器的一种,它只能通过迭代来逐个获取元素,不支持直接用[]访问特定位置的元素。
你的需求拆解
你想要把iter_commit生成的每一组(index, schema),分别作为Parse函数的RoWnum和Link参数,用线程池批量处理。那正确的做法是直接把生成器传给线程池的starmap方法(而不是map),因为starmap会自动把生成器里的每个元组拆成多个参数传给目标函数。
修正后的完整代码
from multiprocessing.pool import ThreadPool from functools import partial import os from os import path __folder__ = os.getcwd() # 根据你的实际路径调整 def iter_commit(LogFileName): with open(path.join(__folder__, LogFileName)) as LogFileName_file: for index, schema in enumerate(LogFileName_file): if len(schema) > 10: # 修正换行符的写法,原来的写法是错误的,应该用'\n' yield index, schema.rstrip('\n') def makePool(cP, func, iters): try: pool = ThreadPool(cP) # 用starmap_async替代map_async,因为func需要接收两个参数 pool.starmap_async(func, iters).get(99999) pool.close() pool.join() except Exception as e: print(f'Pool Error: {str(e)}') raise finally: pool.terminate() def Parse(RoWnum, Link): print(RoWnum, Link) # 调用时直接传入生成器即可,无需拆分下标 strSiteMap = "你的日志文件名.txt" # 替换成实际文件名 makePool(50, Parse, iter_commit(strSiteMap))
关键修改点说明
- 替换
map_async为starmap_async:map会把迭代器的每个元素作为单个参数传给函数,而starmap会把每个元组元素拆成多个参数,正好匹配Parse(RoWnum, Link)的参数需求。
- 移除生成器的下标访问:
直接把iter_commit(strSiteMap)整个生成器传给makePool,线程池会自动迭代生成器里的每一组(index, schema)。 - 修正换行符处理:
原来的换行符写法无效,Python里换行符用\n表示,改成schema.rstrip('\n')才能正确去除行尾的换行。
额外补充:如果需要单独获取生成器的某个元素
如果只是想取生成器里的单个元素(比如第一个),可以用next()函数:
gen = iter_commit(strSiteMap) first_index, first_schema = next(gen) # 获取第一个元素
但这只适合获取少量元素,你的场景是批量处理所有元素,所以用starmap是最优解。
内容的提问来源于stack exchange,提问作者Dmitrij Holkin
相关产品推荐
相关产品推荐

