题
我如何在Python检查EOF?我发现这里的文本分离后的最后一块没有被添加到返回列表在我的代码中的错误。或者,也许有表达这种功能的更好的办法?
下面是我的代码:
def get_text_blocks(filename):
text_blocks = []
text_block = StringIO.StringIO()
with open(filename, 'r') as f:
for line in f:
text_block.write(line)
print line
if line.startswith('-- -'):
text_blocks.append(text_block.getvalue())
text_block.close()
text_block = StringIO.StringIO()
return text_blocks
解决方案
您可能会发现很容易解决这个使用 itertools.groupby
def get_text_blocks(filename):
import itertools
with open(filename,'r') as f:
groups = itertools.groupby(f, lambda line:line.startswith('-- -'))
return [''.join(lines) for is_separator, lines in groups if not is_separator]
另一种方法是使用正则表达式以匹配隔板:
def get_text_blocks(filename):
import re
seperator = re.compile('^-- -.*', re.M)
with open(filename,'r') as f:
return re.split(seperator, f.read())
其他提示
结束文件中的条件成立一旦for
语句终止 - 这似乎是最简单的方法minorly修复这段代码(你可以在年底提取text_block.getvalue()
如果您要检查它不追加前空)
这是标准的问题与发射缓冲器。
您不EOF检测 - 这是不必要的。你写的最后一个缓冲区。
def get_text_blocks(filename):
text_blocks = []
text_block = StringIO.StringIO()
with open(filename, 'r') as f:
for line in f:
text_block.write(line)
print line
if line.startswith('-- -'):
text_blocks.append(text_block.getvalue())
text_block.close()
text_block = StringIO.StringIO()
### At this moment, you are at EOF
if len(text_block) > 0:
text_blocks.append( text_block.getvalue() )
### Now your final block (if any) is appended.
return text_blocks
为什么你需要StringIO的吗?
def get_text_blocks(filename):
text_blocks = [""]
with open(filename, 'r') as f:
for line in f:
if line.startswith('-- -'):
text_blocks.append(line)
else: text_blocks[-1] += line
return text_blocks
编辑:固定的功能,其他的建议可能会更好,只是想写类似于原来的一个函数
编辑:假定与文件开始“ - - ”,通过增加空字符串到列表中,你可以“修复”的IndexError或者你可以用这一个:
def get_text_blocks(filename):
text_blocks = []
with open(filename, 'r') as f:
for line in f:
if line.startswith('-- -'):
text_blocks.append(line)
else:
if len(text_blocks) != 0:
text_blocks[-1] += line
return text_blocks
但是,这两个版本看起来有点丑对我来说,REG-EX版本更干净。
这是看你是否有一个空文件的快捷方式:
if f.read(1) == '':
print "EOF"
f.close()
不隶属于 StackOverflow