自定义生成器用于文件筛选

Tim*_*Tim 6 python

我正在编写一个小的包装类open,它将从文本文件中过滤出特定的行,然后在将它们传递给用户之前将它们拆分为名称/值对.当然,这个过程有助于使用生成器实现.

我的"文件"类

class special_file:
    def __init__(self, fname):
        self.fname = fname

    def __iter__(self):
        return self

    def __next__(self):
        return self.next()

    def next(self):
        with open(self.fname, 'r') as file:
            for line in file:
                line = line.strip()
                if line == '':
                    continue
                name,value = line.split()[0:2]
                if '%' in name:
                    continue
                yield name,value
            raise StopIteration()
Run Code Online (Sandbox Code Playgroud)

用户名代码

for g in special_file('input.txt'):
    for n,v in g:
        print(n,v)
Run Code Online (Sandbox Code Playgroud)

遗憾的是,我的代码有两个巨大的问题:1)special_file当它确实需要返回一个元组时返回一个生成器,以及2)StopIteration()永远不会引发异常,因此无限期地重复读取文件.我怀疑这两个问题是相关的,但我对生成器和可迭代序列的理解相当有限.我是否遗漏了一些关于实施发电机的痛苦明显的事情?

编辑:

我通过将第一个生成器移动到循环外部然后循环遍历它来修复我的无限读取问题.

g = special_file('input.txt')
k = next(g)
for n,v in k:
    print(n,v)
Run Code Online (Sandbox Code Playgroud)

但是,我希望用户能够像普通电话一样使用它open:

for n,v in special_file('input.txt'):
    print(n,v)
Run Code Online (Sandbox Code Playgroud)

Jef*_*ado 2

您已经使用生成器实现了迭代器。直接写生成器就可以了。

def special_file(filename):
    with open(filename, 'r') as file:
        for line in file:
            line = line.strip()
            if line == '':
                continue
            name, value, *_ = line.split()
            if '%' in name:
                continue
            yield name, value
Run Code Online (Sandbox Code Playgroud)

请参阅此处,了解可迭代的含义、迭代器是什么以及使用它们的 Python 协议的概述。