2009-03-03 87 views
2

我正在Python中读取一个文件,其中每个记录由一个空的新行分隔。如果文件以两行或多行结尾,则最后一条记录按预期处理,但如果文件以单行结尾,则不处理。 Here's的代码:读取文件时保留最后一个新行

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
数据的
数据B
数据c
\ n
记录2
数据的
数据b
数据c
\ n
\ n

但在这,最后一条记录isn't返回:

记录1
数据
数据B
数据c
\ n
记录2
数据a
数据B
数据c
\ n

我怎样才能从文件中保存的最后一行,以获得最后一个记录?

PS .:我使用术语“保留”,因为我找不到更好的名字。

谢谢。

编辑 最初的代码是一个剥离的版本,只是为了说明问题,但似乎我剥去了太多。现在我发布了所有函数的代码。

更多解释:为文件中的每个记录创建对象SomeObject,记录由空的新行分隔。在记录结束时,它返回对象,以便我可以使用它(保存到数据库,与其他对象进行比较等)。

当文件以一个新行结束时,最后一条记录没有被放弃,这是主要问题。看起来,Python在空白时不读取最后一行。

回答

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 

这不是伟大的代码,但它确实工作;当完成循环时,遗漏了空行的最后一个对象被放弃。

0

line.strip()将在空行上产生一个空字符串。空字符串是假,所以你吞下空行

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

如果你的文件对象(而不是使用in)上调用readline反复(在循环中),应该按照您的期望。比较这些:

>>> 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'] 
5

您可能会发现更经典Python的方向轻微扭动提高代码的可预测性:

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()记录(我完全掩饰)。

+0

您的代码确实符合作者的代码,但是从他的问题的措辞和他的样本数据看,他看起来并不像他想在每个非空行上创建一个新的SomeObject。他希望一行代码能够贡献给一个SomeObject。 – DNS 2009-03-03 18:39:24

+0

啊是的..你说得对。 – 2009-03-03 18:45:35

+0

编辑我的帖子来引用你的DNS。 – 2009-03-03 18:47:01

0

替换open('somefile.txt'):open('somefile.txt').read().split('\n'):和您的代码将工作。

但Jarret Hardie的回答比较好。

相关问题