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

如何改进文件处理生成器函数,确保文件正确关闭且避免代码重复?

解决生成器中文件未正确关闭的问题

针对你遇到的生成器未迭代完时文件无法关闭的问题,有两种简洁的改进方案:

方案一:利用finally块确保文件关闭

直接修改原代码,将文件关闭逻辑移到finally块中——不管生成器是正常迭代完成、中途抛出异常还是被提前终止,finally块都会执行,从而保证文件被正确关闭:

def gen_reader(file, lookups, stopwords):
    is_file = False
    try:
        if isinstance(file, str):
            file = open(file, 'r', encoding='UTF-8')
            is_file = True
        
        lookups = list(map(str.lower, lookups))
        stop_words = list(map(str.lower, stopwords))
        for line in file:
            original_line = line
            line = line.lower()
            if any(lookup in line for lookup in lookups) \
                    and not any(stop_word in line for stop_word in stop_words):
                yield original_line.strip()
    except FileNotFoundError:
        raise FileNotFoundError('File not found')
    finally:
        if is_file:
            file.close()

方案二:用上下文管理器封装文件处理逻辑

如果想让代码更清晰、职责分离,可以用contextlib.contextmanager写一个通用的文件处理上下文,把打开/关闭文件的逻辑抽离出来,避免重复代码:

from contextlib import contextmanager

@contextmanager
def get_file(file):
    is_file = False
    try:
        if isinstance(file, str):
            file = open(file, 'r', encoding='UTF-8')
            is_file = True
        yield file
    finally:
        if is_file:
            file.close()

def gen_reader(file, lookups, stopwords):
    lookups = list(map(str.lower, lookups))
    stop_words = list(map(str.lower, stopwords))
    
    with get_file(file) as f:
        for line in f:
            original_line = line
            line = line.lower()
            if any(lookup in line for lookup in lookups) \
                    and not any(stop_word in line for stop_word in stop_words):
                yield original_line.strip()

这个方案中,get_file上下文会自动处理文件的打开和关闭:如果传入的是文件名,就打开并在结束后关闭;如果是已打开的文件对象,直接返回它且不会额外关闭。生成器只需专注于筛选行的业务逻辑,代码更易维护。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 02:33:20