在生成器函数中处理文件

问题描述 投票:0回答:2

我要创建一个生成器,它接受文件或文件对象的名称、我们在一行中查找的单词以及告诉我们应该在遇到它们时立即跳过这一行的停止词。

我编写了一个生成器函数,但我注意到,在我的实现中,我无法确定如果我打开一个文件,它会在之后关闭,因为不能保证生成器将到达其迭代的末尾。

def gen_reader(file, lookups, stopwords):
    is_file = False
    try:
        if isinstance(file, str):
            file = open(file, 'r', encoding='UTF-8')
            is_file = True
    except FileNotFoundError:
        raise FileNotFoundError('File not found')

    else:
        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()
    if is_file:
        file.close()

我打算使用上下文管理器“with”并将搜索代码放入其中,但如果我已经获得了文件,那么我会再次编写相同的代码,这不会很好,不是吗?

你对我如何改进我的代码有什么想法,我已经考虑过了。

python file generator
2个回答
0
投票

我不确定“生成器将到达迭代结束”是什么意思。您在读取文件时是否有正在写入的文件?

如果是这样,你应该看看这个 Python 中读取大文件的惰性方法?

否则你不必担心生成器的完成。

使用打开的文件重写此内容,并考虑是否可以使用集合而不是列表进行查找


0
投票

如果您只将文件对象传递给您的函数,然后您可以随时关闭文件对象,也许会更好

def gen_reader(file, lookups, stopwords):
    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()

# an usage example
with open("xxfile", "r") as f:
    for line in gen_reader(f, ["w1", "w2",...], ["st1", "st2", ...]):
        # do something with line you have found
        ...  
# file would be closed here 
© www.soinside.com 2019 - 2024. All rights reserved.