我在Python中读取一个文件,其中每个记录由一个空的新行分隔.如果文件以两个或多个新行结束,则按预期处理最后一个记录,但如果文件以单个新行结尾,则不处理.这是代码:
def fread(): record = False for line in open('somefile.txt'): if line.startswith('Record'): record = True d = SomeObject() # do some processing with line d.process(line) if not line.strip() and record: yield d record = False for record in fread(): print(record)
在这个数据样本中,一切都按预期工作('---'是一个空行):
记录1
数据a
数据b
数据c
\n
记录2
数据a
数据b
数据c
\n
\n
但在此,最后的记录没有返回:
记录1
数据a
数据b
数据c
\n
记录2
数据a
数据b
数据c
\n
如何保留文件中的最后一个新行以获取最后一条记录?
PS.:我使用术语"保留",因为我找不到更好的名字.
谢谢.
编辑 原始代码是一个剥离版本,只是为了说明问题,但似乎我剥离了太多.现在我发布了所有功能代码.
更多解释:SomeObject
为文件中的每个记录创建对象,并且记录由空的新行分隔.在记录结束时,它会返回对象以便我可以使用它(保存到数据库,与其他对象进行比较等).
当文件以单个新行结束时的主要问题是,最后一条记录没有产生.似乎Python在空白时不会读取最后一行.
现在写的方式可能无论如何都不起作用; 与d = SomeObject()
你的循环内,正在为每一行创建了一个新的SomeObject.然而,如果我理解正确,你想要的是空行之间的所有行都贡献给那个对象.你可以这样做:
def fread(): d = None for line in open('somefile.txt'): if d is None: d = SomeObject() if line.strip(): # do some processing else: yield d d = None if d: yield d
这不是很好的代码,但确实有效; 当循环完成时,最后一个错过空行的对象就会产生.
您可能会发现在更经典的pythonic方向上有轻微的扭曲可以提高代码的可预测性:
def fread(): for line in open('text.txt'): if line.strip(): d = SomeObject() yield d raise StopIteration for record in fread(): print record
在Python中结束生成器的首选方法是使用StopIteration异常,尽管通常并非绝对必要.使用if line.strip()
简单意味着如果在剥离空格后仍然存在任何内容,您将获得收益.SomeObject()的构造可以在任何地方......我只是碰巧移动它以防SomeObject的构造很昂贵,或者如果行为空则不会发生副作用.
编辑:为了后人的缘故,我会在这里留下我的答案,但是下面的DNS得到了正确的意图,其中几行有助于同一个SomeObject()记录(我完全掩饰了).