Come verificare la presenza di EOF in Python?
Domanda
Come faccio a verificare la presenza di EOF in Python? Ho trovato un bug nel mio codice dove l'ultimo blocco di testo dopo il separatore non viene aggiunto alla lista di ritorno. O forse c'è un modo migliore di esprimere questa funzione?
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
Soluzione
Si potrebbe trovare più facile per risolvere questo 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 è quella di utilizzare un espressione regolare 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())
Altri suggerimenti
L'end-of-file condizione è non appena la dichiarazione for
termina - che sembra il modo più semplice per risolvere minorly questo codice (è possibile estrarre text_block.getvalue()
alla fine se si desidera controllare non è vuoto prima di aggiungerlo) .
Questo è il problema di serie con emissione di buffer.
Non rilevare EOF - che è inutile. Si scrive l'ultimo tampone.
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
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: Fissa 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 sembrano un po 'brutto per me, la versione reg-ex è molto più pulito.
Questo è un modo veloce per vedere se si dispone di un file vuoto:
if f.read(1) == '':
print "EOF"
f.close()