我正在围绕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()
for g in special_file('input.txt'):
for n,v in g:
print(n,v)
遗憾的是,我的代码有两个巨大的问题:1)special_file
返回一个生成器,当它确实需要返回一个元组时,2)。我怀疑这两个问题是相关的,但我对生成器和可迭代序列的理解相当有限。我是否遗漏了一些关于实施发电机的痛苦明显的事情?StopIteration()
异常永远不会被提升所以文件无限重复读取
我通过将第一个生成器移动到循环外部然后循环遍历它来修复我的无限读取问题。
g = special_file('input.txt')
k = next(g)
for n,v in k:
print(n,v)
但是,我希望用户能像普通电话open
一样使用它:
for n,v in special_file('input.txt'):
print(n,v)
答案 0 :(得分: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
请参阅here,了解可迭代的含义,迭代器的含义以及使用它们的python协议。
答案 1 :(得分:1)
只需更改
def __iter__(self):
return self
到
def __iter__(self):
return next(self)
它按预期工作!
感谢@ Leva7的建议。