2015-03-30 11 views
11

Mi viene sempre confuso se una funzione genera un IOError o OSError (o entrambi?). Qual è la regola principale dietro questi tipi di eccezioni, qual è la differenza tra loro e quando viene sollevata?Differenza tra IOError e OSError?

Inizialmente ho pensato che OSError sia per cose come il rifiuto dell'autorizzazione, ma aprire un file senza autorizzazioni solleverà un IOError.

+4

* Modificato nella versione 3.3: ' EnvironmentError', 'IOError',' WindowsError', 'VMSError',' socket.error', 'select.error' e' mmap.error' sono stati uniti in 'OSError'. * basta lanciare 'OSError' e dimenticare' IOError'. –

+0

@MartijnPieters Grazie, ho aggiunto il tag Python 2. Il solo lancio di OSError mi suona bene, tuttavia ho sempre difficoltà a sapere quando una funzione come "shutil.copyfile()" o "os.access()" solleva IOError o OSError (deve sempre cercarlo) –

+2

Vedi anche https://www.python.org/dev/peps/pep-3151/ per lo sfondo su questo, ti aiuterà a mettere le due eccezioni in prospettiva. –

risposta

21

C'è poca differenza tra i due tipi. Infatti, anche gli sviluppatori core di Python hanno concordato che non c'è alcuna differenza reale e rimosso IOError in Python 3 (ora è un alias per OSError). Vedi PEP 3151 - Reworking the OS and IO exception hierarchy:

While some of these distinctions can be explained by implementation considerations, they are often not very logical at a higher level. The line separating OSError and IOError , for example, is often blurry. Consider the following:

>>> os.remove("fff") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
OSError: [Errno 2] No such file or directory: 'fff' 
>>> open("fff") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
IOError: [Errno 2] No such file or directory: 'fff' 

Sì, è di due tipi di eccezione differenti con il messaggio esattamente lo stesso errore.

Per il proprio codice, attenersi al lancio OSError. Per le funzioni esistenti, controllare la documentazione (dovrebbe dettaglio ciò che è necessario prendere), ma si può tranquillamente prendere entrambi:

try: 
    # ... 
except (IOError, OSError): 
    # handle error 

Citando nuovamente il PEP:

In fact, it is hard to think of any situation where OSError should be caught but not IOError , or the reverse.

+0

o: 'tranne EnvironmentError:' (che è quindi la classe base di WindowsError, mmap.error, shutil.Error, ecc. Anche su PY2) – kxr