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
È stato utile?

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()
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top