2010-01-03 5 views
8

Comment vérifier EOF en Python? J'ai trouvé un bogue dans mon code où le dernier bloc de texte après le séparateur n'est pas ajouté à la liste de retour. Ou peut-être existe-t-il une meilleure façon d'exprimer cette fonction?Comment vérifier EOF en Python?

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 
+0

Essayez maintenant, fixe ma fonction x2 = ( –

Répondre

3

Vous trouverez peut-être plus facile de résoudre ce problème 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 regular expression 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()) 
+0

Des réponses intéressantes Mark. Je ne connaissais pas les outils, merci. – ajushi

+0

+1 Pour la version RegEx, la version d'itertools est légèrement cryptique. –

+0

J'ai essayé la version d'itertools sur l'interpréteur ineractive et elle renvoie une chaîne vide. lignes semble être un objet itertools._grouper – ajushi

1

La fin de fichier condition est que dès que la déclaration 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 que ce n'est pas vide avant de l'ajouter).

+0

Merci Alex Ma solution sale est d'ajouter text_blocks .append (text_block.getvalue()) et text_block.close() sous le bloc for.Cela marche mais ce n'est pas DRY:/ – ajushi

0

Pourquoi avez-vous besoin de 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 à celle d'origine.

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 regarder un peu moche pour moi, la version reg-ex est beaucoup plus propre.

+0

Cela manque toujours le dernier bloc –

+0

Pourriez-vous s'il vous plaît fournir des données d'entrée test? –

+0

@maiku le test Les données d'entrée sont un vidage SQL par phpMyAdmin. Je dois séparer le texte dans blo cks séparés par une ligne qui commence par - -... – ajushi

0

Ce problème est le standard avec des tampons émettant.

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 
1
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 
-2

C'est un moyen rapide de voir si vous avez un fichier vide:

if f.read(1) == '': 
print "EOF" 
f.close() 
+0

Non, car il n'y a pas d'espace entre les ''. J'ai testé cela sur un fichier avec juste un espace, et il n'a pas détecté que le fichier était vide. – AndroidDebaser

+1

Si un fichier contient un espace, il n'est pas vide. – Dave

Questions connexes