2010-07-09 8 views
39

Sto utilizzando il modulo CSV per leggere un file delimitato da tabulazioni. Codice qui sotto:Python: no csv.close()?

z = csv.reader(open('/home/rv/ncbi-blast-2.2.23+/db/output.blast'), delimiter='\t') 

Ma quando aggiungo Z.close() per terminare del mio script ottengo ed errore "csv.reader' oggetto non ha attributo 'vicino'"

z.close() 

Così come faccio a chiudere "Z"?

risposta

40

Il lettore è in realtà solo un parser. Quando lo chiedi per una riga di dati, delega l'azione di lettura all'oggetto sottostante file e converte semplicemente il risultato in un insieme di campi. Quindi non c'è bisogno di chiudere il lettore; sarebbe un'operazione senza significato.

È necessario assicurarsi di chiudere l'oggetto sottostante file, tuttavia. In Python 2.5+, ecco il modo per farlo:

with open('/home/rv/ncbi-blast-2.2.23+/db/output.blast') as f: 
    z = csv.reader(f, delimiter='\t') 

Se non hai familiarità con il with statement, racchiude in pratica il suo contenuto in un blocco try...finally che chiude il file nella parte finally. Per Python 2.5 è necessaria l'importazione __future__ per abilitare l'istruzione with. Se hai bisogno di mantenere la compatibilità con le versioni precedenti di Python come 2.4, dovresti chiudere tu stesso usando try...finally.


Grazie a Jared per sottolineare problemi di compatibilità con la dichiarazione with.

27

Non si chiudono direttamente i lettori CSV; dovresti invece chiudere qualunque oggetto simile a file venga usato. Ad esempio, nel tuo caso, si direbbe:

f = open('/home/rv/ncbi-blast-2.2.23+/db/output.blast') 
z = csv.reader(f, delimiter='\t') 
... 
f.close() 

Se si utilizza una versione recente di Python, è possibile utilizzare l'istruzione with, per esempio

with open('/home/rv/ncbi-blast-2.2.23+/db/output.blast') as f: 
    z = csv.reader(f, delimiter='\t') 
    ... 

Questo ha il vantaggio che f sarà chiusa, anche se si lancia un'eccezione o altrimenti return all'interno del con-blocco, che tale caso porterebbe al file rimanendo aperti nell'esempio precedente. In altre parole, è fondamentalmente equivalente a un blocco try/finally, ad es.

f = open('/home/rv/ncbi-blast-2.2.23+/db/output.blast') 
try: 
    z = csv.reader(f, delimiter='\t') 
    ... 
finally: 
    f.close() 
3

Non si chiude il risultato del metodo reader(), si chiude il risultato del metodo open(). Quindi, utilizzare due dichiarazioni: foo=open(...); bar=csv.reader(foo). Quindi è possibile chiamare foo.close().

Non ci sono punti bonus assegnati per fare in una riga ciò che può essere più leggibile e funzionale in due.

Problemi correlati