在读取文件时保留最后一个新行

时间:2009-03-03 17:38:44

标签: python file

我在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在空白时不会读取最后一行。

5 个答案:

答案 0 :(得分:6)

现在写的方式可能无论如何都不起作用;在循环中使用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

这不是很好的代码,但确实有效;当循环完成时,最后一个错过空行的对象就会产生。

答案 1 :(得分:5)

你可能会发现在更经典的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()记录(我完全掩饰了)。

答案 2 :(得分:0)

line.strip()将在空行上产生一个空字符串。空字符串为False,因此您吞下空行

>>> bool("\n".strip())
False
>>> bool("\n")
True

答案 3 :(得分:0)

如果您在文件对象上反复(循环)调用readline(而不是使用in),它应该按预期工作。比较这些:

>>> x = open('/tmp/xyz')
>>> x.readline()
'x\n'
>>> x.readline()
'\n'
>>> x.readline()
'y\n'
>>> x.readline()
''
>>> open('/tmp/xyz').readlines()
['x\n', '\n', 'y\n']

答案 4 :(得分:0)

open('somefile.txt'):替换为open('somefile.txt').read().split('\n'):,您的代码就可以了。

但Jarret Hardie的答案更好。