2015-08-01 8 views
6

So che in Python il metodo file.close() non ha alcun valore di ritorno, ma non riesco a trovare alcuna informazione se in alcuni casi genera un'eccezione. Se non lo fa, suppongo che la seconda parte di questa domanda sia superflua.file.close() gestione delle eccezioni all'interno di una istruzione with in Python

In caso affermativo, quale sarebbe il modo "corretto" per gestire il metodo file.close() generando un'eccezione all'interno di un'istruzione "con" utilizzata per aprire il file?

C'è una situazione in cui file.close() potrebbe non riuscire immediatamente dopo che un file è stato aperto e letto correttamente?

+0

Se stai usando Python 2.5 o versioni successive, un blocco 'with' chiuderà automaticamente il file per te. Non c'è bisogno di dichiarare esplicitamente 'close()' in quel caso. – Daniel

+1

@Daniel, OP usa il tag python 3.x. @Bitrex puoi stampare l'errore se succede avvolgendo la tua istruzione 'with' con un' try: tranne Exception, e: print (e) ' – awbemauler

+2

con le istruzioni puoi lanciare eccezioni senza modo di gestirle se non eseguendo il wrapping in try/eccezione.con/tranne è stato proposto ma abbattuto. con le dichiarazioni sono zucchero sintattico per i casi di uso semplice in cui non è prevista alcuna eccezione. Vedi http://stackoverflow.com/questions/8774830/how-with-is-better-than-try-catch-to-open-a-file-in-python per una discussione estesa. –

risposta

4

Sì, file.close() può generare un'eccezione IOError. Questo può accadere quando il file system utilizza le quote, ad esempio. Vedere la C close() function man page:

Non controllare il valore di ritorno di close() è un errore di programmazione comune, ma comunque gravi. È possibile che gli errori relativi a un'operazione precedente write(2) vengano segnalati per la prima volta allo close() finale. La mancata verifica del valore restituito al momento della chiusura del file può comportare una perdita di dati silenziosa. Questo può essere osservato in particolare con NFS e con quota disco.

Un valore restituito diverso da zero della funzione C close() porta ad Python sollevando un'eccezione IOError.

Se si voleva gestire questa eccezione, mettere un blocco try...exceptintorno il with dichiarazione:

try: 
    with open(filename, mode) as fileobj: 
     # do something with the open file object 
except IOError as exc: 
    # handle the exception 

Naturalmente, il IOError potrebbe anche essere stata generata durante l'apertura .

+0

'Naturalmente, l'IOError potrebbe anche essere stato lanciato durante l'apertura. In tal caso, si utilizza un [' ExitStack'] (https://docs.python.org/3/library/contextlib.html#contextlib.ExitStack) per assicurarsi che fosse [sollevato quando si esce] (https://docs.python.org/3/library/contextlib.html#catching-exceptions-from-enter-methods). – Navith

+1

@Navith oppure aprire prima l'oggetto file e * quindi * utilizzarlo come gestore di contesto. –

-1

È possibile utilizzare

file object = open(file_name [, access_mode][, buffering]) 

Poi si controlla

file.closed 

E 'Restituisce vero se il file viene chiuso e false altrimenti.

+0

Questo non inizia nemmeno a rispondere alla domanda * fa 'file.close()' lancia qualche eccezione? * L'OP è ** non ** chiedendo come verificare se un oggetto file è aperto o chiuso. –

+0

Oh, mi dispiace - non ho letto bene la Q. –

+0

Va tutto bene; benvenuto in SO. Mentre rispondi alle domande sul sito, ricorda di leggerle attentamente prima di inviare una risposta. In alternativa, puoi lasciare un commento sulla domanda, quando guadagni abbastanza reputazione. – Daniel

1

close può generare eccezioni, ad esempio, se si esaurisce lo spazio sul disco mentre sta tentando di scaricare le ultime scritture, o se si è estratta la chiavetta USB, il file era acceso.

Per quanto riguarda il modo corretto per affrontare questo, ciò dipende dai dettagli della vostra applicazione. Forse vuoi mostrare all'utente un messaggio di errore. Forse vuoi chiudere il tuo programma. Forse vuoi riprovare qualunque cosa stavi facendo, ma con un file diverso. Qualunque sia la risposta che scegli, probabilmente verrà implementata con un blocco try - except in qualunque livello del tuo programma sia il migliore per affrontarlo.