You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌套函数用Yield:无需直接迭代生成器独立访问生成对象

解决方案:让get_all_files成为生成器函数

首先看你当前代码的核心问题:get_all_files里用了return result,这会导致函数在第一次循环(处理2000年的文件)就直接返回,后面2001-2003年的文件根本不会被处理。而你需要保留main和get_all_files的模块分离,同时能逐个访问每个生成的对象,最直接的修改就是把get_all_files改成生成器函数,不用动retrieve_file和main的核心逻辑。

修改步骤

  • 把get_all_files里的return result替换成yield result,让它在每次循环时返回一个处理后的结果,直到所有年份处理完成。
  • retrieve_file不需要改成yield,它的职责就是处理单个文件并返回对应的结果(本地文件名或StringIO对象),当前逻辑完全没问题。

修改后的完整代码

# retrieve_file函数保持原有逻辑不变
def retrieve_file(content, to_download, filename):
    if to_download:
        # 将文件下载到本地计算机
        with open(filename, 'wb') as f:
            f.write(content)
        return filename
    else:
        # 不下载,保留为文件对象
        output = StringIO()
        output.write(content)
        return output  # 这里不需要替换为yield

# 修改后的get_all_files,转为生成器函数
def get_all_files(to_download):
    for year in [2000, 2001, 2002, 2003]:
        content = download_file(year)
        result = retrieve_file(content, to_download, 'file-%s.pdf' % year)
        yield result  # 用yield代替return,逐个返回处理结果

# main函数无需修改,它本来就是迭代生成器的逻辑
def main():
    for file in get_all_files(True):
        parse_file(file)

为什么这样可行?

当main调用get_all_files(True)时,会得到一个生成器对象,迭代它的时候会逐个执行get_all_files里的循环,每次yield出一个处理后的文件结果(要么是本地文件名,要么是StringIO对象),完全满足你“独立访问每个生成的对象”的需求。同时这种修改完全保留了main和get_all_files的模块分离,不需要调整它们的调用关系,也不会影响retrieve_file的单一职责。

内容的提问来源于stack exchange,提问作者toothpick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:02:17