Question
Comment puis-je vérifier EOF en Python? J'ai trouvé un bug dans mon code où le dernier bloc de texte après le séparateur ne soit pas ajouté à la liste de retour. Ou peut-être qu'il ya une meilleure façon d'exprimer cette fonction?
Voici mon code:
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
La solution
Vous trouverez peut-être plus facile de résoudre ce en utilisant 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]
Une autre alternative est d'utiliser un expression régulière pour correspondre aux séparateurs:
def get_text_blocks(filename):
import re
seperator = re.compile('^-- -.*', re.M)
with open(filename,'r') as f:
return re.split(seperator, f.read())
Autres conseils
La fin de fichier condition est que dès que la déclaration de for
se termine - qui semble la façon la plus simple de fixer minorly ce code (vous pouvez extraire text_block.getvalue()
à la fin si vous voulez vérifier ce n'est pas vide avant annexant) .
Ceci est le problème standard avec des tampons d'émission.
Vous ne détectez pas EOF - c'est inutile. Vous écrivez le dernier tampon.
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
Pourquoi avez-vous besoin StringIO ici?
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
EDIT: Correction de la fonction, d'autres suggestions pourraient être mieux, je voulais juste écrire une fonction similaire à l'original
.EDIT: le fichier commence On suppose par « - - », en ajoutant une chaîne vide à la liste que vous pouvez « fixer » le IndexError ou vous pouvez utiliser celui-ci:
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
Mais les deux versions semblent un peu laid pour moi, la version reg-ex est beaucoup plus propre.
Ceci est un moyen rapide de voir si vous avez un fichier vide:
if f.read(1) == '':
print "EOF"
f.close()