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

使用生成器读取文件时如何避免打印GeneratorExit异常信息

解决生成器忽略GeneratorExit的错误

这个问题的根源在于你用了裸except:语句,它会捕获包括GeneratorExit在内的所有异常——而这个异常是Python在生成器被强制关闭时(比如你的with块结束、文件被关闭,但生成器还没遍历完)自动抛出的,目的是让生成器正常清理并退出。当你捕获了它却不处理,Python就会抛出那个警告。

下面是几种修复方案,按推荐程度排序:

1. 精准捕获JSON解析异常(推荐)

只捕获json.loads()可能抛出的解析错误,不要用裸except。Python 3.5及以上版本可以直接捕获json.JSONDecodeError:

import json

def json_generator(f):
    for line in f.read().splitlines():
        try:
            yield json.loads(line)
        except json.JSONDecodeError:
            # 跳过解析失败的行
            pass

如果是Python 3.4及更早版本,json.loads()解析失败会抛出ValueError,可以捕获这个类型:

import json

def json_generator(f):
    for line in f.read().splitlines():
        try:
            yield json.loads(line)
        except ValueError:
            pass

这样就不会捕获GeneratorExit,生成器可以正常响应关闭信号,不会再出现那个错误。

2. 手动处理GeneratorExit(不推荐,仅作参考)

如果你因为某些原因必须使用裸except,那需要在捕获后重新抛出GeneratorExit,让生成器正常退出:

import json

def json_generator(f):
    try:
        for line in f.read().splitlines():
            try:
                yield json.loads(line)
            except:
                pass
    except GeneratorExit:
        # 重新抛出异常,让生成器正常关闭
        raise

不过这种写法不够优雅,也容易隐藏其他未知错误,所以优先推荐第一种方案。

额外优化:处理大文件更高效

你的代码里f.read().splitlines()会一次性把整个文件加载到内存,如果是超大JSON行文件,内存占用会很高。可以改成直接迭代文件对象,逐行读取,更节省内存:

import json

def json_generator(f):
    for line in f:
        # 可选:去掉行首尾的空白和换行符
        cleaned_line = line.strip()
        # 跳过空行
        if not cleaned_line:
            continue
        try:
            yield json.loads(cleaned_line)
        except json.JSONDecodeError:
            pass

这样修改后,即使是几个G的大文件,也能流畅处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:34:25