2010-01-03 1 views
8

Come controllo EOF in Python? Ho trovato un bug nel mio codice in cui l'ultimo blocco di testo dopo il separatore non viene aggiunto alla lista di ritorno. O forse c'è un modo migliore per esprimere questa funzione?Come verificare EOF in Python?

Ecco il mio codice:

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

Prova subito, fissa la mia funzione x2 = ( –

risposta

3

Potresti trovare più facile la soluzione utilizzando 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] 

Un'altra alternativa è usare un regular expression per abbinare i separatori:

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

Risposte interessanti Marco. Non sapevo di itertools, grazie. – ajushi

+0

+1 Per la versione RegEx, la versione di itertools è leggermente criptica. –

+0

Ho provato la versione itertools sull'interprete ineractive e restituisce una stringa vuota. le linee sembrano essere un oggetto itertools._grouper – ajushi

1

L'end-of-file condizione è non appena la dichiarazione for termina - che sembra il modo più semplice per risolvere minorly questo codice (si può estrarre text_block.getvalue() alla fine se vuoi controllare che non sia vuoto prima di aggiungerlo).

+0

Grazie Alex La mia soluzione sporca era di aggiungere text_blocks .append (text_block.getvalue()) e text_block.close() sotto il blocco per. Funziona ma non è ASCIUTTO:/ – ajushi

0

Perché avete bisogno di StringIO qui?

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: Fisso la funzione, altri suggerimenti potrebbe essere migliore, volevo solo scrivere una funzione simile a quella originale.

EDIT: Assunta il file inizia con "- -", con l'aggiunta di stringa vuota alla lista è possibile "fissare" l'IndexError o si potrebbe utilizzare questo:

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 

Ma entrambe le versioni guarda un un po 'brutto per me, la versione reg-ex è molto più pulita.

+0

Manca ancora l'ultimo blocco –

+0

Potresti fornire i dati di input del test? –

+0

@maiku il test i dati di input sono un dump SQL di phpMyAdmin. Devo separare il testo in blo cks separati da una linea che inizia con - -... – ajushi

0

Questo è il problema standard emettono buffer.

Non si rileva EOF: è inutile. Scrivi l'ultimo buffer.

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

questo è un modo veloce per vedere se si dispone di un file vuoto:

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

No, perché non c'è spazio tra "". Ho provato questo su un file con solo uno spazio, e non ha rilevato che il file era vuoto. – AndroidDebaser

+1

Se un file contiene uno spazio non è vuoto. – Dave